diff --git a/articles/monogame/howto/HowTo_AsyncProgramming.md b/articles/monogame/howto/HowTo_AsyncProgramming.md new file mode 100644 index 0000000..c8bf7e6 --- /dev/null +++ b/articles/monogame/howto/HowTo_AsyncProgramming.md @@ -0,0 +1,49 @@ +--- +title: How to work with Asynchronous Methods in MonoGame +description: This topic describes how you can work with asynchronous methods in MonoGame. +--- + +# Working with Asynchronous Methods in MonoGame + +This topic describes how you can work with asynchronous methods in MonoGame. + +MonoGame provides many methods that operate _asynchronously_ for operations that may take longer than the desired render-cycle length. + +Asynchronous methods consist of four elements: + +* A **Begin** call that begins the asynchronous process. **Begin** methods return an [IASyncResult](http://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx) object that can be used to poll for completion if a callback function is not used to detect the completion of the operation. +* An **End** call that ends the asynchronous process and returns objects or data requested by the **Begin** call. Calling the corresponding **End** method for each **Begin** method is important to prevent deadlocks and other undesirable behavior. +* An optional _callback_ method that is called by the system when the asynchronous operation completes. This is passed to the **Begin** call. +* An optional, arbitrary _tracking object_ that can be supplied to **Begin** to uniquely identify a particular asynchronous request. This object is part of the _IASyncResult_ returned by **Begin**, and is also present in the callback method's _**IASyncResult**_ parameter. Because of this, it also can be used to pass arbitrary data to the callback method when the asynchronous process completes. + +The two most common methods of working with asynchronous methods are to check for completion by polling or by callback. This topic describes both methods. + +For exhaustive information about asynchronous methods, see [Asynchronous Programming Design Patterns](http://msdn.microsoft.com/library/ms228969.aspx) on MSDN. + +## To poll for asynchronous method completion + +1. Call the asynchronous **Begin** method, and save the returned _**IASyncResult**_ object to a variable that will be checked for completion. + +2. In your update code, check [IsCompleted](http://msdn.microsoft.com/en-us/library/system.iasyncresult.iscompleted.aspx). + +3. When [IsCompleted](http://msdn.microsoft.com/en-us/library/system.iasyncresult.iscompleted.aspx) is **true**, call the **End** method that corresponds to the **Begin** method called in step 1. + +### To use a callback to check for asynchronous method completion + +1. Call the asynchronous **Begin** method, passing it an [AsyncCallback](http://msdn.microsoft.com/en-us/library/system.asynccallback.aspx) method that will be called when the asynchronous process is completed. + + > [AsyncCallback](http://msdn.microsoft.com/en-us/library/system.asynccallback.aspx) methods must return void, and take a single parameter: [IASyncResult](http://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx). + +2. In the callback, call the **End** method that corresponds to the **Begin** method called in step 1. + + > The **End** method typically returns any data or objects requested by the **Begin** call. + +## See Also + +[Asynchronous Programming Design Patterns](http://msdn.microsoft.com/library/ms228969.aspx) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_AutomaticRotation.md b/articles/monogame/howto/HowTo_AutomaticRotation.md new file mode 100644 index 0000000..5b27aeb --- /dev/null +++ b/articles/monogame/howto/HowTo_AutomaticRotation.md @@ -0,0 +1,20 @@ +--- +title: How to manage automatic rotation and scaling +description: A walkthrough what is involved in figuring out if two objects collide for MonoGame! +--- + +# Automatic Rotation and Scaling + +This topic describes automatic rotation and scaling in the MonoGame Framework. Rotation and scaling are done in hardware at no performance cost to the game. + +If your game supports more than one display orientation, as specified by [SupportedOrientations](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.SupportedOrientations) and described with [DisplayOrientation](xref:Microsoft.Xna.Framework.DisplayOrientation), the MonoGame Framework automatically rotates and scales the game when the **OrientationChanged** event is raised. + +The current back buffer resolution is scaled, and can be queried by using [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth) and [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight). These values will not be the same as the nonscaled screen resolution, which can be queried by using [DisplayMode](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.DisplayMode) or [ClientBounds](xref:Microsoft.Xna.Framework.GameWindow.ClientBounds). + +If you leave [SupportedOrientations](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.SupportedOrientations) set to **DisplayOrientation.Default**, orientation is automatically determined from your [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth) and [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight). If the [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth) is greater than the [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight), the game will run in the landscape orientation and automatically switch between **LandscapeLeft** and **LandscapeRight** depending on the position which the user holds the phone. To run a game in the portrait orientation, set the [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth) to a value smaller than the [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight). + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© The MonoGame Team. diff --git a/articles/monogame/howto/HowTo_CollisionDetectionOverview.md b/articles/monogame/howto/HowTo_CollisionDetectionOverview.md new file mode 100644 index 0000000..d58f2a1 --- /dev/null +++ b/articles/monogame/howto/HowTo_CollisionDetectionOverview.md @@ -0,0 +1,81 @@ +--- +title: How to test collisions with Bounding Volumes +description: A walkthrough what is involved in figuring out if two objects collide for MonoGame! +--- + +# Bounding Volumes and Collisions + +Collision detection determines whether objects in a game world overlap each other. + +The MonoGame Framework provides several classes and methods to speed implementation of collision detection systems in games. + +* [Bounding Volume Classes](#bounding-volume-classes) +* [Non-Bounding Volume Classes](#non-bounding-volume-classes) +* [Contains and Intersects Methods](#contains-and-intersects-methods) +* [Adding New Collision Data Structures](#adding-new-collision-data-structures) + +## Bounding Volume Classes + +The MonoGame Framework has three classes that represent three-dimensional volumes. Use a bounding volume class to approximate the volume occupied by a complex object using a volume that is less complex and faster for performing collision checking. All of the bounding volume classes support intersection and containment tests with each other and the plane and ray classes. + +### Bounding Sphere + +The [BoundingSphere Structure](xref:Microsoft.Xna.Framework.BoundingSphere) represents the space occupied by a sphere. + +There are several benefits of using a bounding sphere for collision detection. + +* Sphere to sphere checks are very fast. To check for collision between two spheres, the distance between the centers of the spheres is compared to the sum of the radii of both spheres. If the distance is less than the combined radii of both spheres, the spheres intersect. +* The [BoundingSphere Structure](xref:Microsoft.Xna.Framework.BoundingSphere) class is compact. It stores only a vector representing its center and its radius. +* Unlike a bounding box, a bounding sphere doesn’t need to be recreated if the model rotates. If the model being bounded rotates, the bounding sphere will still be large enough to contain it. +* Moving a bounding sphere is inexpensive. Just add a value to the center. + +There is one major drawback to using the bounding sphere class for collision detection. + +* Unless the object being approximated is sphere shaped, the bounding sphere will have some empty space, which could result in false positive results. Long narrow objects will have the most empty space in their bounding spheres. + +### Bounding Box + +The [BoundingBox Structure](xref:Microsoft.Xna.Framework.BoundingBox) represents the space occupied by a box. The bounding box class is axis aligned. Each face of the bounding box is perpendicular to the x-axis, the y-axis, or the z-axis. + +There are several benefits of using the bounding box for collision detection. + +* The bounding box class fits rectangular shapes aligned with the axis very well. Compared to the bounding sphere class, the bounding box class provides a much tighter fit for non-rotated rectangular objects. +* Because the bounding box class is axis aligned, you can make certain assumptions that result in collision checks between bounding boxes being quicker than a bounding box that can be rotated. + +There are a few drawbacks of using the bounding box for collision detection. + +* Rotating a bounding box causes it to no longer be axis aligned. Because of this, if you rotate a model being bounded, you will need to recreate the bounding box. Doing so can be slow, since all the points in an object are iterated through to get the bounding box. If the model has not changed orientation, you can translate the bounding box instead of recreating it. +* If the model being bounded is not aligned to the axis, the bounding box will have some empty space. The amount of empty space will be greatest when the object is rotated 45 degrees from an axis. +* Empty space in the bounding box can result in false positives when checking for collision. + +### Bounding Frustum + +Use a [BoundingFrustum Class](xref:Microsoft.Xna.Framework.BoundingFrustum) to create a bounding volume that corresponds to the space visible to the camera. You create a bounding frustum from the combined view and projection matrix that the camera is using currently. If the camera moves or rotates, you need to recreate the bounding frustum. The bounding frustum isn’t used to determine when two objects collide, but rather when an object intersects with the volume of space viewable by the camera. Objects that do not intersect and are not contained by the bounding frustum are not visible to the camera and don’t need to be drawn. For complex models, this can reduce the number of pixels that need to be rendered. + +## Non-Bounding Volume Classes + +### Plane + +The [Plane Structure](xref:Microsoft.Xna.Framework.Plane) describes a 2D plane. The plane is defined by a normal vector (perpendicular to the plane) and a point on the plane. The plane class supports intersection tests with the bounding volume classes. The plane class’s intersection test returns the tested object's position relative to the plane. The return value indicates whether the object intersects the plane. If the object does not intersect the plane, the return value indicates whether the object is on the plane’s front side or back side. + +### Ray + +The [Ray Structure](xref:Microsoft.Xna.Framework.Ray) describes a ray starting at a point in space. The ray structure supports intersection tests with the bounding volume classes. The return value of the ray intersection tests is the distance the intersection occurred at, or null if no intersection occurred. + +### Model + +In addition to the information needed to draw a model, the [Model Class](xref:Microsoft.Xna.Framework.Graphics.Model) contains bounding volumes for its parts. When a model is imported, the content pipeline calculates the bounding sphere for each of the model's parts. To check for collision between two models, you can compare the bounding spheres for one model to all of the bounding spheres of the other model. + +## Contains and Intersects Methods + +Bounding volume classes have methods to support two types of collision tests: intersection tests and containment tests. The intersects methods check whether the two objects being tested overlap in any way. As soon as the test finds that the objects do intersect, it returns without trying to determine the degree of the intersection. The contains methods determine whether the objects simply intersect or whether one of the objects is completely contained by the other. Since the intersects methods need only determine whether an intersection occurred, they tend to be faster than the contains methods. + +## Adding New Collision Data Structures + +When implementing other bounding volume classes and intersection tests, you will probably need to add a custom content pipeline processor. For example, your game might need to use convex hulls for collision detection. You could use a custom processor to determine the convex hull and then place it in the model's tag field. Then, when the model is loaded at run time, the convex hull information would be available in the model. For more information, see [Extending a Standard Content Processor](Content_Pipeline/HowTo_Extend_Processor.md). + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_ExitNow.md b/articles/monogame/howto/HowTo_ExitNow.md new file mode 100644 index 0000000..4a93712 --- /dev/null +++ b/articles/monogame/howto/HowTo_ExitNow.md @@ -0,0 +1,66 @@ +--- +title: How to exit a Game Immediately +description: Demonstrates how to exit a game in response to user input. +--- + +# Exiting a Game Immediately + +Demonstrates how to exit a game in response to user input. + +## Exiting a Game Without Finishing the Current Update + +> **Note* some platforms react differently to **Game.Exit**, so be sure to test on a device! + +### To exit the game loop without running any remaining code in the update handler + +1. Derive a class from [Game](xref:Microsoft.Xna.Framework.Game). + +2. Create a method that checks [KeyboardState.IsKeyDown](xref:Microsoft.Xna.Framework.Input.KeyboardState) for the state of the **ESC** key. + +3. If the ESC key has been pressed, call [Game.Exit](xref:Microsoft.Xna.Framework.Game.Exit) and return **true**. + + ```csharp + bool checkExitKey(KeyboardState keyboardState, GamePadState gamePadState) + { + // Check to see whether ESC was pressed on the keyboard + // or BACK was pressed on the controller. + if (keyboardState.IsKeyDown(Keys.Escape) || + gamePadState.Buttons.Back == ButtonState.Pressed) + { + Exit(); + return true; + } + return false; + } + ``` + +4. Call the method in **Game.Update**, and return from **Update** if the method returned **true**. + + ```csharp + GamePadState gamePadState = GamePad.GetState(PlayerIndex.One); + KeyboardState keyboardState = Keyboard.GetState(); + + // Check to see if the user has exited + if (checkExitKey(keyboardState, gamePadState)) + { + base.Update(gameTime); + return; + } + ``` + +5. Create a method to handle the **Game.Exiting** event. + + The **Exiting** event is issued at the end of the tick in which [Game.Exit](xref:Microsoft.Xna.Framework.Game.Exit) is called. + + ```csharp + void Game1_Exiting(object sender, EventArgs e) + { + // Add any code that must execute before the game ends. + } + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_MobileBestPractices.md b/articles/monogame/howto/HowTo_MobileBestPractices.md new file mode 100644 index 0000000..f496f6b --- /dev/null +++ b/articles/monogame/howto/HowTo_MobileBestPractices.md @@ -0,0 +1,86 @@ +--- +title: How to apply Best Practices for MonoGame Games +description: The practices discussed here will help you have the most success possible with your MonoGame game. +--- + +# Best Practices for MonoGame Games + +The practices discussed here will help you have the most success possible with your MonoGame game. + +This overview covers the following topics. + +* [Polish Your Game](#polish-your-game) +* [Build Intuitive and Fun Controls](#build-intuitive-and-fun-controls) +* [Support Changing Screen Orientation](#support-changing-screen-orientation) +* [Audio Tips](#audio-tips) +* [Respond Correctly to Back Button Use](#respond-correctly-to-back-button-use) +* [Diligently Save Game State](#diligently-save-game-state) + +## Polish Your Game + +It is difficult to over emphasize how important polish is for a successful game. The best game ideas and the most stable code do not compare to a game with an extra level of polish. Polish can be defined as putting in the extra effort to make your game look and feel its best. It also is: + +* The difference between a basic menu with buttons that just work and the same menu with polish. It may take time to add a small flourish of animation for each button press, sound effect, and styled buttons to a menu, but doing so makes a big difference. +* Smooth menu operation and intuitive controls. +* Smooth transitions among screens, modes, and levels. + +## Build Intuitive and Fun Controls + +Avoid simulating traditional controls such as thumbsticks in MonoGame games. That type of control takes away useful space from the gameplay area and is not platform friendly. Use gestures for user input. Games that are engaging and naturally fun have controls that are natural to the platform. + +|Control|Description| +|-|-| +|Touch|Touch control systems will feel natural to MonoGame users. Design games from the beginning to take full advantage of the touch screen. The touch screen is the primary way users interact with their phone, and users expect to interact with games in the same way.| +|Back Button|Although there are other buttons on the device, only the **Back** button is available to the game. Use the **Back** button for pausing and exiting the game.| +|Gestures|Design your gameplay to use touch gestures in natural ways. For example: allowing players to draw paths on the screen to direct gameplay, or allowing for group selection by stretching an on-screen rectangle around play pieces. Consider allowing navigation by dragging the landscape, and allowing users to rotate by touching and rotating two fingers.| + +## Support Changing Screen Orientation + +MonoGame supports three screen orientation views: portrait, landscape left, and landscape right. Portrait view is the default view for applications. The **Start** button is always presented in portrait view. In portrait view, the page is oriented vertically with the steering buttons displayed at the bottom of the phone. + +In both landscape views, the **Status Bar** and **Application Bar** remain on the side of the screen that has the **Power** and **Start** buttons. Landscape left has the **Status Bar** on the left, and landscape right has the **Status Bar** on the right. + +Routinely check current screen orientation and enable gameplay regardless of how the phone is held. + +For more detailed information on screen rotation see [Automatic Rotation and Scaling](HowTo_AutomaticRotation.md). + +## Audio Tips + +Audio can enrich an application and add needed polish. Playing audio should also dependent on user preference. Consider these tips when building audio into your game: + +* Play sound effects at an average volume to avoid forcing the player to adjust the devices volume during the game. +* Allow sound effects and background music to be turned on and off by users. +* Play directional sounds that reflect a location of the originating element on the screen. + +For more detailed information on audio see [Creating and Playing Sounds](../whatis/WhatIs_Audio.md). + +## Respond Correctly to Back Button Use + +Games must respond to use of the **Back** button, or "esc" on Windows. MonoGame consistently uses **Back** to move backward through the UI. Games must implement this behavior as follows: + +* During gameplay, the game can do one of the following: + * Present a contextual pause menu (dialog). Pressing the **Back** button again while in the pause menu closes the menu and resumes the game. + * Navigate the user to the prior menu screen. Pressing the **Back** button again should continue to return the user to the previous menu or page. + +* Outside of gameplay, such as within the game's menu system, pressing **Back** must return to the previous menu or page. +* At the game’s initial (start) screen, pressing **Back** must exit the game. + +It is a good practice in case the player exits the game to automatically save the game state while the pause menu is shown. + +## Diligently Save Game State + +On MonoGame, a game might be exited at any time. An incoming call may interrupt gameplay, or the user might quit the game by using the **Home** or **Search** buttons to use other applications. We recommend saving game state whenever possible to protect the user's time investment in the game. We also recommend that you make a distinction between the automatically saved game state and the user's explicitly saved games. Automatically saved games should be viewed as a backup in case the game ends unexpectedly, but should not replace the user's ability to save the game at a chosen time or place. + +If you implement automatic game saving, check for an automatically saved state when the game launches. If found, let the user choose to resume the game from the automatically saved state or from a specific manually saved game, if present. During the save process, we also recommend that you display a visual cue warning users not to press the **Search** or **Home** button because the action could cause the game to exit before the save is complete. + +## See Also + +[Creating a your first MonoGame Game](https://monogame.net/articles/getting_started/index.html) +[Setting Aspect ratios for your game](./graphics/HowTo_AspectRatio.md) +[Saving data using MonoGame](HowTo_SaveData.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_PlayerResize.md b/articles/monogame/howto/HowTo_PlayerResize.md new file mode 100644 index 0000000..f110f9c --- /dev/null +++ b/articles/monogame/howto/HowTo_PlayerResize.md @@ -0,0 +1,34 @@ +--- +title: How to resize a Game +description: Demonstrates how to handle the resizing of the active game window. +--- + +# Adding Window Resizing Functionality + +## To add player window resizing to a game + +1. Derive a class from [Game](xref:Microsoft.Xna.Framework.Game). + +2. Set [Game.GameWindow.AllowUserResizing](xref:Microsoft.Xna.Framework.GameWindow.AllowUserResizing) to **true**. + +3. Add an event handler for the **ClientSizeChanged** event of [Game.Window](xref:Microsoft.Xna.Framework.Game.Window). + + ```csharp + this.Window.AllowUserResizing = true; + this.Window.ClientSizeChanged += new EventHandler(Window_ClientSizeChanged); + ``` + +4. Implement a method to handle the **ClientSizeChanged** event of [Game.Window](xref:Microsoft.Xna.Framework.Game.Window). + + ```csharp + void Window_ClientSizeChanged(object sender, EventArgs e) + { + // Make changes to handle the new window size. + } + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_SaveData.md b/articles/monogame/howto/HowTo_SaveData.md new file mode 100644 index 0000000..46358a4 --- /dev/null +++ b/articles/monogame/howto/HowTo_SaveData.md @@ -0,0 +1,113 @@ +--- +title: How to Save and Load data using MonoGame +description: Demonstrates reading and writing data in MonoGame projects. +--- + +# Writing Data + +MonoGame is based on DotNet, which provides access to the System.IO namespace that delivers methods to interact with the file system + +For detailed information about using Isolated Storage in games, see [Local Data Storage for Windows Phone](http://go.microsoft.com/fwlink/?LinkId=254759) in the Windows Phone documentation. + +## Saving data using System.IO + +Other saving + +## Reading data using System.IO + +Other saving + +## To save game data with System.IO.IsolatedStorage + +1. Add a **using System.IO.IsolatedStorage** statement at the beginning of the source file in which you'll be using the namespace. + + ```csharp + using System.IO.IsolatedStorage; + ``` + +2. Use [IsolatedStorageFile.GetUserStoreForApplication](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.getuserstoreforapplication.aspx) to get an [IsolatedStorageFile](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.aspx) object that can be used to create files and directories, or to read and write existing files. + + > When [IsolatedStorageFile.GetUserStoreForApplication](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.getuserstoreforapplication.aspx) is called within a MonoGame game for Windows (but not for Xbox 360 or Windows Phone), an InvalidOperationException will result. To avoid this exception, use the [GetUserStoreForDomain](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.getuserstorefordomain.aspx) method instead. + + ```csharp + #if WINDOWS + IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForDomain(); + #else + IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForApplication(); + #endif + ``` + +3. Use [IsolatedStorageFile.OpenFile](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.openfile.aspx) to open a file for writing, and use the returned [IsolatedStorageFileStream](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefilestream.aspx) to write data to the file. + + ```csharp + protected override void OnExiting(object sender, System.EventArgs args) + { + // Save the game state (in this case, the high score). + #if WINDOWS + IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForDomain(); + #else + IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForApplication(); + #endif + + // open isolated storage, and write the savefile. + IsolatedStorageFileStream fs = null; + using (fs = savegameStorage.CreateFile(SAVEFILENAME)) + { + if (fs != null) + { + // just overwrite the existing info for this example. + byte[] bytes = System.BitConverter.GetBytes(highScore); + fs.Write(bytes, 0, bytes.Length); + } + } + + base.OnExiting(sender, args); + } + ``` + +## Reading save game data with System.IO.IsolatedStorage + +Reading saved data written in this way uses a very similar process. For example: + +```csharp + protected override void Initialize() + { + // open isolated storage, and load data from the savefile if it exists. +# if WINDOWS + using (IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForDomain()) +# else + using (IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForApplication()) +# endif + { + if (savegameStorage.FileExists(SAVEFILENAME)) + { + using (IsolatedStorageFileStream fs = savegameStorage.OpenFile(SAVEFILENAME, System.IO.FileMode.Open)) + { + if (fs != null) + { + // Reload the saved high-score data. + byte[] saveBytes = new byte[4]; + int count = fs.Read(saveBytes, 0, 4); + if (count > 0) + { + highScore = System.BitConverter.ToInt32(saveBytes, 0); + } + } + } + } + } + base.Initialize(); + } +``` + +> [IsolatedStorageFile](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.aspx) provides many more methods than are shown here, including support for asynchronous reads and writes. For complete documentation, see [Local Data Storage for Windows Phone](http://go.microsoft.com/fwlink/?LinkId=254759) in the Windows Phone documentation, and the [IsolatedStorage](http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.aspx) reference on MSDN. + +## Serializing data + +Text Data + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_TimingOut.md b/articles/monogame/howto/HowTo_TimingOut.md new file mode 100644 index 0000000..cba83e4 --- /dev/null +++ b/articles/monogame/howto/HowTo_TimingOut.md @@ -0,0 +1,66 @@ +--- +title: How to exit a Game After a Time Out +description: Demonstrates how to exit a game after a period of time (such as inactivity) has passed. +--- + +# Adding Time-Out Functionality to a Game + +## To make a game time out + +1. Create a class that derives from [Game](xref:Microsoft.Xna.Framework.Game). + +2. Determine the desired time-out limit in milliseconds. + + ```csharp + // Time out limit in ms. + static private int TimeOutLimit = 4000; // 4 seconds + ``` + +3. Add a variable for tracking the elapsed time since the most recent user activity. + + ```csharp + // Amount of time that has passed. + private double timeoutCount = 0; + ``` + +4. When user input is checked, set a flag indicating whether any user activity has taken place. + + ```csharp + GamePadState blankGamePadState = new GamePadState( + new GamePadThumbSticks(), new GamePadTriggers(), new GamePadButtons(), + new GamePadDPad()); + ``` + +5. In **Update**, if there has not been any user activity, increment the tracking variable by the elapsed time since the last call to **Update**. + +6. If there has been some user activity, set the tracking variable to zero. + + ```csharp + // Check to see if there has been any activity + if (checkActivity(keyboardState, gamePadState) == false) + { + timeoutCount += gameTime.ElapsedGameTime.Milliseconds; + } + else + timeoutCount = 0; + ``` + +7. Check whether the value of the tracking variable is greater than the time-out limit. + +8. If the variable is greater than the limit, perform some time-out logic such as playing an idle animation or, in this case, exit the game. + + ```csharp + // Timeout if idle long enough + if (timeoutCount > TimeOutLimit) + { + Exit(); + base.Update(gameTime); + return; + } + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/HowTo_VariableStepGameLoop.md b/articles/monogame/howto/HowTo_VariableStepGameLoop.md new file mode 100644 index 0000000..b12574e --- /dev/null +++ b/articles/monogame/howto/HowTo_VariableStepGameLoop.md @@ -0,0 +1,48 @@ +--- +title: How to update a game with Variable or Fixed Timing +description: Demonstrates how to set up the runtime to call your Update method using variable or fixed timing. +--- + +# Updating with Variable or Fixed Timing + +Demonstrates how to set up the runtime to call your Update method using variable or fixed timing. + +There are two techniques for setting how often your **Update** method is called. Variable timing means to call **Update** as soon as other work finishes; this implies that it is up to a game developer to ensure that your render loop happens quickly enough so that **Update** will be called often enough to exceed your minimum frame rate. Fixed timing means that **Update** is called each time a fixed interval of time has passed. Fixed timing guarantees that **Update** will be called, however, so you may drop frames if the previous work needs to be interrupted to call **Update**. + +## To use a variable time step + +1. Create a class that derives from [Game](xref:Microsoft.Xna.Framework.Game). + +2. Set [IsFixedTimeStep](xref:Microsoft.Xna.Framework.Game.IsFixedTimeStep) to **false**. + + This causes the [Update](xref:Microsoft.Xna.Framework.Game) method to be called as often as possible, instead of being called on a fixed interval. + + ```csharp + this.IsFixedTimeStep = false; + ``` + +## To use a fixed time step + +1. Create a class that derives from [Game](xref:Microsoft.Xna.Framework.Game). + +2. Set [IsFixedTimeStep](xref:Microsoft.Xna.Framework.Game.IsFixedTimeStep) to **true**. + + ```csharp + this.IsFixedTimeStep = true; + ``` + + This causes the [Update](xref:Microsoft.Xna.Framework.Game) method to be called each time the fixed time interval has passed. + +3. Set **TargetElapsedTime** to a fixed interval of time. + + This example sets the time between calls to 16 milliseconds. + + ```csharp + this.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 16); // Update() is called every 16 milliseconds + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_ChangePitchAndVolume.md b/articles/monogame/howto/audio/HowTo_ChangePitchAndVolume.md new file mode 100644 index 0000000..2a2cee7 --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_ChangePitchAndVolume.md @@ -0,0 +1,110 @@ +--- +title: How to adjust Pitch and Volume +description: Demonstrates how to manipulate the pitch and volume of sound effects as they play. +requireMSLicense: true +--- + +The **[SoundEffect.Play](xref:Microsoft.Xna.Framework.Audio.SoundEffect.Play)** method allows you to specify the pitch and volume of a sound to play. However, after you call **[Play](xref:Microsoft.Xna.Framework.Audio.SoundEffect.Play)**, you cannot modify the sound. Using **[SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance)** for a given **[SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect)** allows you to change the **pitch** and **volume** of a sound at any time during playback. + +> [!NOTE] +> The pitch of a sound changes the frequency of the sound, which in turn changes the speed of the sound. The volume of a sound changes the amplitude of the sound, which in turn changes the loudness of the sound. + +## Change Pitch and Volume of Sound + +1. Declare a **[SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect)** and a [Stream](http://msdn.microsoft.com/en-us/library/system.io.stream.aspx) file by using the method shown in [Playing a Sound](HowTo_PlayASound.md). In addition to the method described in [Playing a Sound](HowTo_PlayASound.md), declare a **[SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance)** and a **Sound Effect** field member. We also create two float fields for **pitch** and **volume** to store the pitch and volume of the sound effect and assign initial values to them. + + ```csharp + // place these usings at the top of the file + using System.IO; + using Microsoft.Xna.Framework; + using Microsoft.Xna.Framework.Audio; + using Microsoft.Xna.Framework.Graphics; + using Microsoft.Xna.Framework.Input; + + // place these fields at the top of the class + private SoundEffect soundEffect; + private SoundEffectInstance soundEffectInstance; + private float pitch = 0.75f; + private float volume = 0.5f; + ``` + + > [!NOTE] + > Usings are declared at the top of the file to ensure that the necessary namespaces are available to the class. The fields are declared at the top of the class to ensure that they are accessible to all methods in the class. + +2. In the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game.LoadContent) method, set the **SoundEffectInstance** object to the return value of [SoundEffect.CreateInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance). + +3. In the **[Game.LoadContent](xref:Microsoft.Xna.Framework.Game.LoadContent)** method, set the **SoundEffectInstance** object to the return value of **[SoundEffect.CreateInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance)**. We also optionally define a variable **soundFile** to store the location of the sound file being used with the **[TitleContainer.OpenStream](xref:Microsoft.Xna.Framework.TitleContainer#Microsoft_Xna_Framework_TitleContainer_OpenStream_System_String_)** method, which is accessed with the **using** keyword, and include a field member variable called **soundEffect**, to hold the stream. + + ```csharp + using Stream soundfile = TitleContainer.OpenStream(@"Content\Sound__FileName.wav"); + soundEffect = SoundEffect.FromStream(soundfile); + soundInstance = soundEffect.CreateInstance(); + ``` + +4. Adjust the sound to the desired level using the [SoundEffectInstance.Pitch](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Pitch) and [SoundEffectInstance.Volume](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Volume) properties. + + ```csharp + // Play Sound + soundEffectInstance.Play(); + ``` + + > [!NOTE] + > An instance will play once, to loop the sound, you can use the **[SoundEffectInstance.IsLooped](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.IsLooped)** property to set the sound to loop. Also note that the sound will not repeat until the sound has finished playing. You can utilise the **[SoundEffectInstance.State](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.State)** property to check if the sound is playing, paused or stopped. Use the **[SoundEffectInstance.Stop](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Stop)** method to stop the sound. + +## An Extended Example + + 1. Below the **[Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_)** method, create a new method called **IsKeyPressed**, which will check if a specified key is pressed and return a boolean value of true if it has been pressed. + + ```csharp + private bool IsKeyPressed(Keys key) + { + return Keyboard.GetState().IsKeyDown(key); + } + + ``` + + 2. In the **[Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_)** method, check if the **Space** key is pressed and adjust the pitch and volume of the sound effect accordingly. The pitch and volume values are adjusted by +0.1f each time the **Space key** is pressed. The pitch values are clamped to a minimum value of -1.0f and a maximum value of 1.0f, and the volume values are then clamped to a minimum value of 0f and a maximum value of 1.0f. This is done to ensure that the pitch and volume values are within valid ranges. + + ```csharp + // Check if the SpaceKey is pressed and play the instance + if (IsKeyPressed(Keys.Space)) + { + pitch += 0.1f; + volume += 0.1f; + pitch = MathHelper.Clamp(pitch, -1.0f, 1.0f); + volume = MathHelper.Clamp(volume, 0f, 1.0f); + soundEffectInstance.Pitch = pitch; + soundEffectInstance.Volume = volume; + soundEffectInstance.Play(); + } + ``` + + > [!NOTE] + > The **MathHelper.Clamp** method is used to ensure that the pitch and volume values are within the valid range. The pitch value is clamped between -1 and 1, while the volume value is clamped between 0 and 1. + + > [!NOTE] + > The check for the keypress does not prevent the call to the method repeating so any value entered may peak the value in a single key press. To prevent this, you can add a delay to the key press check, or use a boolean value to check if the key has been pressed and released. + +## Concepts + +[Playing a Sound](HowTo_PlayASound.md) + +Demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). + +[Looping a Sound](HowTo_LoopASound.md) + +Demonstrates how to loop a sound. + +[Creating and Playing Sounds](../../whatis/WhatIs_Audio.md) + +Provides overviews about audio technology, and presents predefined scenarios to demonstrate how to use audio. + +## Reference + +[SoundEffect Class](xref:Microsoft.Xna.Framework.Audio.SoundEffect) + +Provides a loaded sound resource. + +[SoundEffectInstance Class](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) + +Provides a single playing, paused, or stopped instance of a [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) sound. diff --git a/articles/monogame/howto/audio/HowTo_LoopASound.md b/articles/monogame/howto/audio/HowTo_LoopASound.md new file mode 100644 index 0000000..c283ddc --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_LoopASound.md @@ -0,0 +1,50 @@ +--- +title: How to loop Sounds +description: This section demonstrates how to loop a sound. +--- + +# Looping a Sound + +This section demonstrates how to loop a sound. + +## Simple Sound Looping + +Not much extra code is needed to continuously loop a sound file in your game. Since the [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) class does not provide looping support, you'll need to allocate a [SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) object. The following procedure builds on the sample code provided in the [Playing a Sound](HowTo_PlayASound.md) topic. + +### To loop a sound + +1. Follow the instructions show in [Playing a Sound](HowTo_PlayASound.md) topic. + +2. To be able to loop a sound you will need to declare a [SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) object, and set it to the return value of [SoundEffect.CreateInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance). + + ```csharp + SoundEffectInstance instance = soundEffect.CreateInstance(); + ``` + +3. Set [SoundEffectInstance.IsLooped](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.IsLooped) to **true** and then play the sound. + + ```csharp + instance.IsLooped = true; + ``` + +## Concepts + +[Playing a Sound](HowTo_PlayASound.md) + +Demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). + +## Reference + +[SoundEffect Class](xref:Microsoft.Xna.Framework.Audio.SoundEffect) + +Provides a loaded sound resource. + +[SoundEffectInstance Class](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) + +Provides a single playing, paused, or stopped instance of a [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) sound. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_Microphone.md b/articles/monogame/howto/audio/HowTo_Microphone.md new file mode 100644 index 0000000..f95c36a --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_Microphone.md @@ -0,0 +1,53 @@ +--- +title: How to work with Microphones +description: This topic provides basic information about microphone usage in games. +--- + +# Working with Microphones + +This topic provides basic information about microphone usage in games. + +## Supported Microphone Devices + +The Microphone API is only implemented on OpenAL based platforms at this time. This includes iOS/Android and Desktop projects using DesktopGL. + +## Capabilities of the Microphone API + +The MonoGame Microphone API has the following functionality: + +* Captures the audio stream from a microphone. +* Submits and controls a stream of audio buffers for playback using the [DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) object. +* Plays back audio. + +## Microphone API Process Workflow + +The Microphone API behaves like a simple audio recorder with a configurable capture buffer. It has been designed with the following development process workflow: + +1. Select the microphone connected to the device. +2. Configure the microphone's capture buffer size. +3. Control the recording using standard transport controls (Start and Stop). +4. Retrieve the captured audio using the [GetData](xref:Microsoft.Xna.Framework.Audio.Microphone) method. + +Also, you can use the **BufferReady** event handler of the [Microphone](xref:Microsoft.Xna.Framework.Audio.Microphone) class if you want to be notified when the audio capture buffer is ready to be processed. + +## Concepts + +[Creating and Playing Sounds](../../whatis/WhatIs_Audio.md) + +Provides overviews about audio technology, and presents predefined scenarios to demonstrate how to use audio. + +## Reference + +[DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) + +Provides properties, methods, and events for play back of the audio buffer. + +[Microphone](xref:Microsoft.Xna.Framework.Audio.Microphone) + +Provides properties, methods, and fields and events for capturing audio data with microphones. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_PlayASong.md b/articles/monogame/howto/audio/HowTo_PlayASong.md new file mode 100644 index 0000000..7dd83f1 --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_PlayASong.md @@ -0,0 +1,74 @@ +--- +title: How to play a Song / music +description: Demonstrates how to play a song from a media library. +--- + +# Playing a Song + +Demonstrates how to play a song from a media library. + +The [Albums](xref:Microsoft.Xna.Framework.Media.MediaLibrary.Albums) property provides access to the media library, and the [Play](xref:Microsoft.Xna.Framework.Media.MediaPlayer) method plays a song. Consider any current audio playback when using the [Play](xref:Microsoft.Xna.Framework.Media.MediaPlayer) method. If the user currently is playing a different song, the [Stop](xref:Microsoft.Xna.Framework.Media.MediaPlayer) method can be used to stop the current song. + +## To play a song from a random album in a user's media library + +The following demonstrates how to play a song from a randomly picked album (shuffle). + +1. Declare [MediaLibrary](xref:Microsoft.Xna.Framework.Media.MediaLibrary) and [Random](http://msdn.microsoft.com/en-us/library/system.random.aspx). + + ```csharp + MediaLibrary sampleMediaLibrary; + Random rand; + ``` + +2. Initialize [MediaLibrary](xref:Microsoft.Xna.Framework.Media.MediaLibrary) and the random number generator in the game's constructor. + + ```csharp + sampleMediaLibrary = new MediaLibrary(); + rand = new Random(); + ``` + +3. Stop the current audio playback by calling [MediaPlayer.Stop](xref:Microsoft.Xna.Framework.Media.MediaPlayer), and then generate a random number that will serve as a valid album index. Next, play the first track in the random album. + + ```csharp + MediaPlayer.Stop(); // stop current audio playback + + // generate a random valid index into Albums + int i = rand.Next(0, sampleMediaLibrary.Albums.Count - 1); + + // play the first track from the album + MediaPlayer.Play(sampleMediaLibrary.Albums[i].Songs[0]); + ``` + +## Concepts + +[Playing a Song from a URI](HowTo_PlaySongfromURI.md) + +Demonstrates how to use the [MediaPlayer](xref:Microsoft.Xna.Framework.Media.MediaPlayer) to play a song from a Uniform Resource Identifier (URI). + +[Media Overview](../../whatis/WhatIs_Audio.md) + +Provides a high-level overview about the capabilities—such as playing music and video and accessing pictures—of the Media API in MonoGame. + +## Reference + +[MediaPlayer Class](xref:Microsoft.Xna.Framework.Media.MediaPlayer) + +Provides methods and properties to play, pause, resume, and stop songs. **MediaPlayer** also exposes shuffle, repeat, volume, play position, and visualization capabilities. + +[MediaLibrary Class](xref:Microsoft.Xna.Framework.Media.MediaLibrary) + +Provides access to songs, playlists, and pictures in the device's media library. + +[MediaPlayer.Play Method](xref:Microsoft.Xna.Framework.Media.MediaPlayer) + +Plays a song or collection of songs. + +[MediaLibrary.Albums Property](xref:Microsoft.Xna.Framework.Media.MediaLibrary.Albums) + +Gets the [AlbumCollection](xref:Microsoft.Xna.Framework.Media.AlbumCollection) that contains all albums in the media library. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_PlayASound.md b/articles/monogame/howto/audio/HowTo_PlayASound.md new file mode 100644 index 0000000..ea4a432 --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_PlayASound.md @@ -0,0 +1,64 @@ +--- +title: How to play a Sound(effect) +description: This topic demonstrates how to play a simple sound by using SoundEffect. +--- + +# Playing a Sound + +This topic demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). + +## To add a sound file to your project + +1. Load your MonoGame game in Visual Studio. + +2. In **Solution Explorer**, right-click the solution's **Content** project. + +3. Click **Add**, and then click **Existing Item**. + +4. Navigate to the .wav file you want to add, and then select it. + +> The selected .wav file is inserted into your project. By default, it is processed by the Content Pipeline, and built wave files are accessed automatically when the game is built. + +### To play a simple sound + +1. Declare a [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) object to hold the sound file. + + ```csharp + // Audio objects + SoundEffect soundEffect; + ``` + +2. Load the sound file using [Content.Load](xref:Microsoft.Xna.Framework.Content.ContentManager). + + ```csharp + soundEffect = Content.Load("kaboom"); + ``` + +3. Play the sound. + + ```csharp + // Play the sound + soundEffect.Play(); + ``` + +## Concepts + +[Looping a Sound](HowTo_LoopASound.md) + +Demonstrates how to loop a sound. + +## Reference + +[SoundEffect Class](xref:Microsoft.Xna.Framework.Audio.SoundEffect) + +Provides a loaded sound resource. + +[SoundEffectInstance Class](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) + +Provides a single playing, paused, or stopped instance of a [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) sound. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_PlaySongfromURI.md b/articles/monogame/howto/audio/HowTo_PlaySongfromURI.md new file mode 100644 index 0000000..2ef70b8 --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_PlaySongfromURI.md @@ -0,0 +1,62 @@ +--- +title: How to play a Song from a URI +description: Demonstrates how to use the MediaPlayer to play a song from a Uniform Resource Identifier (URI). +--- + +# Playing a Song from a URI + +Demonstrates how to use the [MediaPlayer](xref:Microsoft.Xna.Framework.Media.MediaPlayer) to play a song from a Uniform Resource Identifier (URI). + +## To play a song from a URI + +The following steps show you how to play an .mp3 song located on the Internet. + +1. Set [MediaPlayer](xref:Microsoft.Xna.Framework.Media.MediaPlayer) play state to stopped. + + ```csharp + MediaPlayer.Stop(); + ``` + +2. Declare a new instance of [Uri](http://msdn.microsoft.com/en-us/library/system.uri.aspx) using the full URI path to the song. + + ```csharp + Uri uriStreaming = new Uri("http://www.archive.org/download/gd1977-05-08.shure57.stevenson.29303.flac16/gd1977-05-08d02t06_vbr.mp3"); + ``` + +3. Use the [FromUri](xref:Microsoft.Xna.Framework.Media.Song) method to supply an arbitrary string name for the URI, and then pass the [Uri](http://msdn.microsoft.com/en-us/library/system.uri.aspx) object you created in the previous step. + + ```csharp + Song song = Song.FromUri("StreamingUri", uriStreaming); + ``` + +4. Play the song. + + ```csharp + MediaPlayer.Play(song); + ``` + +## Concepts + +[Playing a Song](HowTo_PlayASong.md) + +Demonstrates how to play a song from a user's media library. + +[Media Overview](../../whatis/WhatIs_Audio.md) + +Provides a high-level overview about the capabilities—such as playing music and video and accessing pictures—of the Media API in XNA Game Studio. + +## Reference + +[MediaPlayer Class](xref:Microsoft.Xna.Framework.Media.MediaPlayer) + +Provides methods and properties to play, pause, resume, and stop songs. **MediaPlayer** also exposes shuffle, repeat, volume, play position, and visualization capabilities. + +[Song Class](xref:Microsoft.Xna.Framework.Media.Song) + +Provides access to a song in the song library. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_Record_Microphone.md b/articles/monogame/howto/audio/HowTo_Record_Microphone.md new file mode 100644 index 0000000..544f888 --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_Record_Microphone.md @@ -0,0 +1,90 @@ +--- +title: How to record Sound with a Microphone +description: This topic demonstrates the basics of recording audio using a microphone. +--- + +# Recording Sound with a Microphone + +This topic demonstrates the basics of recording audio using a microphone. + +The procedure shows the bare basics of using the microphone to record audio. In practice, you will want to use UI elements (such as buttons) to start and stop audio recording. + +## To record audio from the microphone + +1. Get the device's default microphone by using [Microphone.Default](xref:Microsoft.Xna.Framework.Audio.Microphone). + + ```csharp + Microphone mic = Microphone.Default; + if (mic == null) + { + return false; // No microphone is attached to the device + } + ``` + +2. Declare a buffer array to hold the audio data, and declare a variable to track the amount of audio that will be recorded. + + ```csharp + // Declare a buffer array to hold the audio data based on the duration of the recording + byte[] buffer = new byte[Microphone.Default.GetSampleSizeInBytes(TimeSpan.FromSeconds(3.0))]; + + // Tracks the amount of data recorded + int bytesRead = 0; + ``` + +3. Begin recording audio, calling method [Microphone.Start](xref:Microsoft.Xna.Framework.Audio.Microphone). + + ```csharp + if (!isMicrophoneRecording) + { + // we are starting to record + timeSpentRecording = 0; + Microphone.Default.Start(); + } + + isMicrophoneRecording = !isMicrophoneRecording; + ``` + +4. While the microphone is recording, call [Microphone.GetData (Byte\[\], Int32, Int32)](xref:Microsoft.Xna.Framework.Audio.Microphone) in your game's [Game.Update](xref:Microsoft.Xna.Framework.Game) method to save the latest recorded audio to the buffer. + + ```csharp + bytesRead += Microphone.Default.GetData(buffer, bytesRead, (buffer.Length - bytesRead)); + ``` + +5. When you are finished recording, set the microphone state to stopped by calling method [Stop](xref:Microsoft.Xna.Framework.Audio.Microphone). + + ```csharp + if (!isMicrophoneRecording) + { + } + + else + { + + Microphone.Default.Stop(); + + // mark the flag that we have some data available. + hasData = true; + } + ``` + +## Concepts + +[Working with Microphones](HowTo_Microphone.md) + +Provides basic information about microphone usage in games for Windows Phone. + +## Reference + +[Microphone](xref:Microsoft.Xna.Framework.Audio.Microphone) + +Provides properties, methods, and fields and events for capturing audio data with microphones. + +[DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) + +Provides properties, methods, and events for play back of the audio buffer. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/HowTo_StreamDataFromWav.md b/articles/monogame/howto/audio/HowTo_StreamDataFromWav.md new file mode 100644 index 0000000..afe2570 --- /dev/null +++ b/articles/monogame/howto/audio/HowTo_StreamDataFromWav.md @@ -0,0 +1,148 @@ +--- +title: How to stream Data from a WAV File +description: This topic describes how to stream an audio file using DynamicSoundEffectInstance. +--- + +# Streaming Data from a WAV File + +This topic describes how to stream an audio file using [DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance). + +## Loading Audio Content + +### To open a wave file for streaming + +1. Create global variables to hold the [DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance), position, count, and data. + + ```csharp + DynamicSoundEffectInstance dynamicSound; + int position; + int count; + byte[] byteArray; + ``` + +2. In the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game.LoadContent) method of your game, open the audio data using [TitleContainer.OpenStream](xref:Microsoft.Xna.Framework.TitleContainer). + + ```csharp + System.IO.Stream waveFileStream = TitleContainer.OpenStream(@"Content\48K16BSLoop.wav"); + ``` + +3. Create a new binary reader to read from the audio stream. + + ```csharp + BinaryReader reader = new BinaryReader(waveFileStream); + ``` + +4. Read the wave file header from the buffer. + + ```csharp + int chunkID = reader.ReadInt32(); + int fileSize = reader.ReadInt32(); + int riffType = reader.ReadInt32(); + int fmtID = reader.ReadInt32(); + int fmtSize = reader.ReadInt32(); + int fmtCode = reader.ReadInt16(); + int channels = reader.ReadInt16(); + int sampleRate = reader.ReadInt32(); + int fmtAvgBPS = reader.ReadInt32(); + int fmtBlockAlign = reader.ReadInt16(); + int bitDepth = reader.ReadInt16(); + + if (fmtSize == 18) + { + // Read any extra values + int fmtExtraSize = reader.ReadInt16(); + reader.ReadBytes(fmtExtraSize); + } + + int dataID = reader.ReadInt32(); + int dataSize = reader.ReadInt32(); + ``` + +5. Store the audio data of the wave file to a byte array. + + ```csharp + byteArray = reader.ReadBytes(dataSize); + ``` + +6. Create the new dynamic sound effect instance using the sample rate and channel information extracted from the sound file. + + ```csharp + dynamicSound = new DynamicSoundEffectInstance(sampleRate, (AudioChannels)channels); + ``` + +7. Store the size of the audio buffer that is needed in the count variable. Submit data in 100 ms chunks. + + ```csharp + count = dynamicSound.GetSampleSizeInBytes(TimeSpan.FromMilliseconds(100)); + ``` + +8. Set up the dynamic sound effect's buffer needed event handler so audio data can be read when it needs more data. + + ```csharp + dynamicSound.BufferNeeded += new EventHandler(DynamicSound_BufferNeeded); + ``` + +9. Implement the buffer needed event handler. + + ```csharp + void DynamicSound_BufferNeeded(object sender, EventArgs e) + { + dynamicSound.SubmitBuffer(byteArray, position, count / 2); + dynamicSound.SubmitBuffer(byteArray, position + count / 2, count / 2); + + position += count; + if (position + count > byteArray.Length) + { + position = 0; + } + } + ``` + +10. Use the controller buttons to play and stop the sound stream. + + ```csharp + protected override void Update(GameTime gameTime) + { + GamePadState gamePadState = GamePad.GetState(PlayerIndex.One); + if (lastGamePadState != gamePadState) + { + if (gamePadState.Buttons.A == ButtonState.Pressed) + { + dynamicSound.Play(); + } + if (gamePadState.Buttons.B == ButtonState.Pressed) + { + dynamicSound.Stop(); + } + lastGamePadState = gamePadState; + } + + base.Update(gameTime); + } + ``` + +## Concepts + +[Playing a Sound](HowTo_PlayASound.md) + +Demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). + +## Reference + +[DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) + +Provides properties, methods, and events for play back of the audio buffer. + +[BufferNeeded](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) + +Event that occurs when the number of audio capture buffers awaiting playback is less than or equal to two. + +[OpenStream](xref:Microsoft.Xna.Framework.TitleContainer) + +Returns a stream to an existing file in the default title storage location. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/index.md b/articles/monogame/howto/audio/index.md new file mode 100644 index 0000000..7327dd4 --- /dev/null +++ b/articles/monogame/howto/audio/index.md @@ -0,0 +1,48 @@ +--- +title: How To tasks for Audio +description: A series of articles to answer common questions related to audio operation! +--- + +# "How To" Articles for Audio + +These articles provide a brief introduction into managing audio in MonoGame games. + +## In This Section + +[Playing a Sound](HowTo_PlayASound.md) + +Demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). + +[Looping a Sound](HowTo_LoopASound.md) + +Demonstrates how to loop a sound. + +[Adjusting Pitch and Volume](HowTo_ChangePitchAndVolume.md) + +Demonstrates how to change pitch and volume of a playing sound. + +[Playing a Song](HowTo_PlayASong.md) + +Demonstrates how to play a song from a user's media library. + +[Playing a Song from a URI](HowTo_PlaySongfromURI.md) + +Demonstrates how to use the [MediaPlayer](xref:Microsoft.Xna.Framework.Media.MediaPlayer) to play a song from a Uniform Resource Identifier (URI). + +[Streaming Data from a WAV File](HowTo_StreamDataFromWav.md) + +Demonstrates how to stream audio from a wave (.wav) file. + +[Recording Sounds with Microphones](HowTo_Microphone.md) + +Topics that provide guidance on writing code to support microphones for MonoGame. + +[Recording Sound with a Microphone](HowTo_Record_Microphone.md) + +Demonstrates the basics of recording audio using a microphone attached to a device. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/audio/toc.yml b/articles/monogame/howto/audio/toc.yml new file mode 100644 index 0000000..4262931 --- /dev/null +++ b/articles/monogame/howto/audio/toc.yml @@ -0,0 +1,2 @@ +- name: Introduction + href: index.md \ No newline at end of file diff --git a/articles/monogame/howto/content_pipeline/HowTo_Add_XML.md b/articles/monogame/howto/content_pipeline/HowTo_Add_XML.md new file mode 100644 index 0000000..e8048ed --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_Add_XML.md @@ -0,0 +1,116 @@ +--- +title: How to add a custom XML Content File to a Project? +description: Describes how to add custom game data as an XML file through the Content Pipeline. +requireMSLicense: true +--- + +Custom game data that is expressed in an XML format can be easily integrated into your game through the MonoGame Content Pipeline. + +This example demonstrates the procedure for integrating custom XML data into the content project of a simple game for the Windows platform. + +### To define game data + +Within the MonoGame solution, you create a new Windows Game Library project. + +1. Right-click the solution node, point to `Add`, click `New Project`, and then select the `MonoGame Game Library` template. + + > [!TIP] + > A `MonoGame Game Library` project is created instead of a Content Pipeline Extension Library project so that the class we will define can be used by both the [Content Importer](https://docs.monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.ContentImporter-1.html) that runs at build-time and the [Content Loader](xref:Microsoft.Xna.Framework.Content.ContentManager#Microsoft_Xna_Framework_Content_ContentManager_Load__1_System_String_) at game runtime. + +2. In the `Name` box, type `MyDataTypes`, and then click `OK`. + +3. In the `Solution Explorer`, delete the existing `Game1.cs` as it is not needed. + +4. `right-click` and select `Add -> Add New Item` to add a new class, call it `PetData.cs` + +5. Double click on `PetData.cs` and replace its contents with the following code to define the `PetData` class. + + ```csharp + namespace MyDataTypes + { + public class PetData + { + public string Name; + public string Species; + public float Weight; + public int Age; + } + } + ``` + +6. Build the `MyDataTypes` project for debug or release to generate the library's dll file (note which profile you used). + +### Add an XML file using the custom data to the game content + +In this procedure, the `MyDataTypes` library is added as a reference in the content project. + +1. In `Solution Explorer`, right-click the game content project, point to `Add Reference`, click the `Projects` tab, select `MyDataTypes`, and then click `OK`. + +2. In the `Solution Explorer`, `right-click` the game content folder, point to `Add`, and then click `New Item`. + +3. In the `Add New Item` dialog box, type `pets.xml` as the file name, and then click `OK`. + +4. Replace the contents of the template file with the following XML code: + + ```xml + + + + + Fifi + Dog + 11 + 6 + + + Bruno + Dog + 21 + 12 + + + Chloe + Cat + 6 + 3 + + + Pickles + Hamster + 0.4 + 1 + + + + ``` + + > [!TIP] + > TO learn how to generate the custom MonoGame XML content from your own classes, refer to the [How to Generate custom XML](HowTo_GenerateCustomXML.md) guide. + +5. Open the `Content.mgcb` content project by double-clicking on it. + + > [!TIP] + > If you have any issues opening the MGCB content project, please refer to the [How to load content](HowTo_GameContent_Add.md) guide. + +6. Click on `Add Existing` from the `Edit -> Add` options in the menu (or the `Add Existing` toolbar button) and select the `pets.xml` file. + +7. Select the root `Content` element in the `Project` tree (left hand window) and then select `References` in the properties panel below. + +8. Click on `Add` and browse to the `bin/debug/netx.0` folder of the `MyDataTypes` project. + +> [!TIP] +> If the folder is empty, return to visual studio and build the `MyDataTypes` project, if it is not built, there is no dll. +> And make sure to choose either the `debug` or `release` folder depending on how the class library is built. + +When you press `F6` to build the solution, it should build successfully, including the custom game content imported from the XML file. + +> [!IMPORTANT] +> Adding the the class library of the data types project to the Content project is critical, else the Content Pipeline does not know how to serialize or deserialize the custom data you have defined. +> Although it is possible to simply serialize `value types` or `value type arrays` without this step. + +To load the data at runtime, see the tutorial [Loading XML Content at Runtime](HowTo_Load_XML.md). + +## See Also + +- [Using an XML File to Specify Content](HowTo_UseCustomXML.md) +- [Adding Content to a Game](HowTo_GameContent_Add.md) diff --git a/articles/monogame/howto/content_pipeline/HowTo_ExtendFontProcessor.md b/articles/monogame/howto/content_pipeline/HowTo_ExtendFontProcessor.md new file mode 100644 index 0000000..30b066e --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_ExtendFontProcessor.md @@ -0,0 +1,149 @@ +--- +title: How to Extend the Font Description Processor to Support Additional Characters? +description: Describes the process of developing a custom content processor needed to add additional characters to a FontDescription object based on the text that is required by the game. +requireMSLicense: true +--- + +In a font description (.spritefont) file, the `` area can be used to add additional characters to a font description. This enables you to use a [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) to render an additional range of characters. + +For some languages, this approach is not ideal. For example, Chinese and Japanese both have many thousands of characters. Adding the full range of characters to `` dramatically increases the size of the font asset and the time required to build the font asset. A better solution adds individual characters whenever the specific characters are needed. You can create a custom content processor to implement this solution. + +In this example, a file called _messages.txt_ contains all the text rendered by the game. The custom processor adds all the characters contained in the text in this file to a [FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription). Then it processes the object in the standard way using the base [FontDescriptionProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontDescriptionProcessor) functionality. All the characters in messages.txt will then be available to the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) object at run time. + +## Using the Font Description Processor + +### To specify the character regions and messages to process + +1. To add a new Sprite Font called DefaultFont to a game project, go to Solution Explorer, right-click the nested Content node, click **Add**, and then click **New Item**. + +2. To add the new sprite font to the game, select the **Sprite Font** template, and then click **Add**. + +3. Modify this file to use an existing font and any additional characteristics you prefer. + + For more information, see [Sprite Font XML Schema Reference](../../whatis/Content_Pipeline/CP_SpriteFontSchema.md). + +4. Add a file named messages.txt to the game project. + +5. Right-click on the game project node in Solution Explorer, click **Add**, and then click **New Item**. + +6. Select the **Text File** template, enter **messages.txt** for the file name, and then click **Add** to add the text file to the game. + +7. In the new text file, enter any messages that will be printed by the font described in the Sprite Font file. + + > We will use the method [File.ReadAllText](http://msdn.microsoft.com/en-us/library/ms143369.aspx) to read the text in this file. This method requires a carriage return ("\\r") or line feed ("\\n") after the last string, so be sure to follow the last line of text in the file with a carriage return or line feed. + +### To create the new content processor project + +The Content Pipeline is part of the build process, and it is separate from your game code. Therefore, you need to create a new assembly that contains the code developed in this topic. Creating this new assembly project is the first step in developing a new processor. + +> **Tip** +> +> It is assumed that you have an existing game project that you will modify. For the purposes of this example, the game project is called "FontGame." + +1. To add the new processor project to the game solution, go to Solution Explorer, right-click the **Solution** node, click **Add**, and then click **New Project**. + +2. In the dialog box, select the template **Content Pipeline Extension Library (4.0)**, enter "FontProcessor" in the **Name** field, and then click **OK**. The new project automatically contains references to the XNA Framework run-time and design-time Content Pipeline assemblies. + +### To extend the font processor + +1. Add the following lines of code, after the last `using` statement: + + ```csharp + using System.IO; + using System.ComponentModel; + ``` + +2. In ContentProcessor1.cs, remove the placeholder code that assigns the processor input (`TInput`) and output (`TOutput`) types. It will not be needed. + +3. Using attributes, add a processor parameter to the beginning of the class declaration. + + This parameter stores the name of the text file that stores the messages displayed by the game. + + ```csharp + [DefaultValue("messages.txt")] + [DisplayName("Message File")] + [Description("The characters in this file will be automatically added to the font.")] + public string MessageFile + { + get { return messageFile; } + set { messageFile = value; } + } + private string messageFile = "messages.txt"; + ``` + +4. Change the derivation of ContentProcessor1 from [ContentProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline) to [FontDescriptionProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontDescriptionProcessor). + +5. Modify the [Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontTextureProcessor) method override to match the following code: + + ```csharp + public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) + ``` + + This modification replaces the template parameter and return types with the proper types needed for the extended font processor. + +6. Register a Content Pipeline dependency on messages.txt. + + This dependency tells the Content Pipeline that if messages.txt changes, the font must be rebuilt. + + ```csharp + string fullPath = Path.GetFullPath(MessageFile); + + context.AddDependency(fullPath); + ``` + +7. Read the contents of the file, and add each letter to the input font one by one. Note that the [Characters](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription) collection keeps track of duplicates automatically. It is not necessary for the user to make sure that each letter is added only once. The **Characters** collection will contain only one instance of each character, no matter how many times **Add** has been called. + + ```csharp + string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8); + + foreach (char c in letters) + { + input.Characters.Add(c); + } + ``` + + In this example, messages.txt has been saved with Unicode UTF-8 encoding, which is why this encoding format is specified in the call to [File.ReadAllText](http://msdn.microsoft.com/en-us/library/ms143369.aspx). The default file encoding format for text files that have been added to a Visual Studio project is Western European (Windows) encoding, corresponding to code page 1252. If your text file uses the default encoding, specify the character encoding as follows: + + string letters = File.ReadAllText( fullPath, System.Text.Encoding.GetEncoding( 1252 + ) ); + +8. Call the existing **Process** method of the base [FontDescriptionProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontDescriptionProcessor) to build the font with the newly requested characters. + + ```csharp + return base.Process(input, context); + ``` + +### To associate the custom font processor with the sprite font + +1. Compile the solution to build **MyFontProcessor**. + + Now you need to add your custom font processor as an available content processor for the game. + +2. From **Solution Explorer**, right-click the **Content** node, and then click **Add Reference**. + +3. From the **Projects** tab, select your content extension project (**FontProcessor**) node, and click **OK**. + + To ensure that the processor project is always up to date when the main game is built, you need to create a project dependency. + +4. In Solution Explorer, right-click the game project (**FontGame**) node, and then click **Project Dependencies**. + +5. Select the check box next to **FontProcessor**, and then click **OK** to add a new dependency so that **FontGame** depends on **FontProcessor**. + +6. Change the content processor for the .spritefont file from **Sprite Font Description - XNA Framework** to the newly created processor. + +7. Select the .spritefont file, and then in the **Properties** window, choose your custom processor from the drop-down list associated with the **ContentProcessor** field. + +When you build the solution, the new processor adds the characters in the messages.txt file to the list of characters available to the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont). + +> **Note** +> +> To debug a Content Pipeline importer or processor, add the following line to the processor code to launch the debugger. +> +> ```csharp +> System.Diagnostics.Debugger.Launch(); +> ``` + +## See Also + +[Extending a Standard Content Processor](./HowTo_Extend_Processor.md) +[Adding New Content Types](../../whatis/Content_Pipeline/CP_Content_Advanced.md) diff --git a/articles/monogame/howto/content_pipeline/HowTo_Extend_Processor.md b/articles/monogame/howto/content_pipeline/HowTo_Extend_Processor.md new file mode 100644 index 0000000..dcc6d69 --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_Extend_Processor.md @@ -0,0 +1,137 @@ +--- +title: How To Extend a Standard Content Processor? +description: Describes how MonoGame lets you modify or extend the behavior of any standard Content Pipeline processor that ships with the product. +requireMSLicense: true +--- + +MonoGame lets you modify or extend the behavior of any standard Content Pipeline processor that ships with the product. See [Standard Content Importers and Content Processors](../../whatis/Content_Pipeline/CP_StdImpsProcs.md) for a description of standard processors. + +Because there are so many asset variants supported by different digital content creation (DCC) tools, it is often useful to be able to modify how one of the standard processors operates. The following examples illustrate some of the kinds of things you might want to do. + +> **Tip** +> +> The following code samples are provided only for demonstration. Most of the functionality described is already available by using parameters on a standard processor. + +## Adding a Scaling Operation to a Processor + +There are many reasons why you might want to modify the existing functionality of a standard processor. Here is one example. If your source assets and your game are at different scales, you may want the processor to scale each model automatically at build time. You can implement such automatic scaling by overriding the [Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) method of the [ModelProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) class, which generates a [Model](xref:Microsoft.Xna.Framework.Graphics.Model). In the override, you first scale the entire scene, and then invoke the base class functionality to process as usual. + +The following code illustrates this technique: + +```csharp + [ContentProcessor] + class ScalingModelProcessor : ModelProcessor + { + public override ModelContent Process( + NodeContent input, ContentProcessorContext context ) + { + MeshHelper.TransformScene( input, Matrix.CreateScale( 10.0f ) ); + return base.Process( input, context ); + } + } +``` + +## Generating Additional Data + +In some cases, you may want to add information to a game asset that a standard processor would not. For example, if a custom effect you want to apply requires tangent or binormal data, you can extend the standard model processor to build this additional data into the asset. To do this, you override the [Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) method of the [ModelProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) class. In the override, navigate the [NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent) hierarchy of the game asset, and call [CalculateTangentFrames](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshHelper) for each [MeshContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshContent) object you find. + +The following code shows how to do this: + +```csharp + [ContentProcessor] + class ModelProcessorWithTangents : ModelProcessor + { + public override ModelContent Process( NodeContent input, ContentProcessorContext context ) + { + GenerateTangentFramesRecursive( input ); + return base.Process( input, context ); + } + + private void GenerateTangentFramesRecursive( NodeContent node ) + { + MeshContent mesh = node as MeshContent; + if (mesh != null) + { + MeshHelper.CalculateTangentFrames( mesh, VertexChannelNames.TextureCoordinate( 0 ), + VertexChannelNames.Tangent( 0 ), VertexChannelNames.Binormal( 0 ) ); + } + + foreach (NodeContent child in node.Children) + { + GenerateTangentFramesRecursive( child ); + } + } + } +``` + +## Changing the Processors Called for Child Objects + +Another useful technique is to override a standard processor, and to change how child objects are processed just by changing the processors they use. + +Consider, for example, the hierarchy of calls through which textures in a model are processed: + +- The standard [ModelProcessor.Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) method is called to process a [NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent) object that represents the root of a scene. +- `ModelProcessor.Process` in turn calls the [ModelProcessor.ConvertMaterial](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) method once for every [MaterialContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MaterialContent) object used in the scene. +- `ModelProcessor.ConvertMaterial` in turn invokes the [MaterialProcessor.Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.MaterialProcessor) method on the [MaterialContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MaterialContent) object passed to it. +- `MaterialProcessor.Process` in turn calls the [MaterialProcessor.BuildTexture](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.MaterialProcessor) method once for each texture in the [MaterialContent.Textures](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MaterialContent.Textures) collection in the `MaterialContent` object passed to it. +- `MaterialProcessor.BuildTexture` in turn invokes the [ModelTextureProcessor.Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessor) method on the [TextureContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent) object passed to it. + +One reason you may want to change how this works is that the `ModelTextureProcessor.Process` method applies texture compression to all textures it processes. This could be DXT1, DXT5, PVRTC, ETC1, RGBA4444 or ATITC depending on target your platform. If textures in your game assets are compressed already, you may want to avoid a second compression. + +> **Tip** +> +> Not all platforms support all types of texture compression. For example DXT1/5 are generally only supported on Desktop graphics cards and some NVidia mobile graphics cards. PVRTC is only supported on iOS and some Android devices with PowerVR graphics cards, and ATITC is only supported on ATI graphics cards. Using the `Compressed` setting for `TextureCompression` for the Texture Processor will let the Pipeline pick the best compression for your target platform. + +### To prevent compression of textures during processing + +Here is how to prevent compression from being applied to model textures during processing. + +1. Create an override of the standard [MaterialProcessor.BuildTexture](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.MaterialProcessor) method, and invoke the [TextureProcessor.Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessor) method, which does no compression, instead of `ModelTextureProcessor.Process`. +2. Create an override of `ModelProcessor.ConvertMaterial` that invokes your override of `MaterialProcessor.BuildTexture` instead of the standard one. + +The first of these overrides could be coded as: + +```csharp + [ContentProcessor] + class NoCompressionMaterialProcessor : MaterialProcessor + { + protected override ExternalReference BuildTexture( + string textureName, ExternalReference texture, ContentProcessorContext context ) + { + return context.BuildAsset( texture, "TextureProcessor" ); + } + } +``` + +There are several things to note about this code. + +- An [ExternalReference](xref:Microsoft.Xna.Framework.Content.Pipeline) is an asset object that is shared between multiple classes, such as a diffuse texture used by more than one material. When such an asset is specified, the Content Manager loads only one copy of the `ExternalReference` at run time and builds it only once, no matter how many references there are to it. +- The [ContentProcessorContext](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext)[BuildAsset](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext) method lets you invoke a processor by name to build the content in an object. +- Although _textureName_, the first argument to `BuildTexture`, is ignored in the override above, you could use it if you wanted to process textures differently depending on normal maps or other criteria. + +Given the processor created by your first override above, you could code the second override: + +```csharp + [ContentProcessor] + class NoCompressionModelProcessor : ModelProcessor + { + protected override MaterialContent ConvertMaterial( + MaterialContent material, ContentProcessorContext context ) + { + return context.Convert( + material, "NoCompressionMaterialProcessor" ); + } + } +``` + +Because this override is processing `MaterialContent` objects in memory rather than `ExternalReference` objects, it uses the [ContentProcessorContext.Convert](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext) function instead of [BuildAsset](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext) to invoke the processor created by your first override. + +After building and installing your new `NoCompressionModelProcessor` (see [Adding a Custom Importer](../../whatis/Content_Pipeline/CP_AddCustomProcImp.md)), you can assign it to any models whose textures are already compressed and no further compression is applied. + +## See Also + +- [Adding New Content Types](../../whatis/Content_Pipeline/CP_Content_Advanced.md) +- [What Is Content?](../../whatis/Content_Pipeline/CP_Overview.md) +- [What is the Content Pipeline?](../../whatis/Content_Pipeline/CP_Architecture.md) +- [Standard Content Importers and Content Processors](../../whatis/Content_Pipeline/CP_StdImpsProcs.md) +- [Adding a Custom Importer](../../whatis/Content_Pipeline/CP_AddCustomProcImp.md) diff --git a/articles/monogame/howto/content_pipeline/HowTo_GameContent_Add.md b/articles/monogame/howto/content_pipeline/HowTo_GameContent_Add.md new file mode 100644 index 0000000..6acc31f --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_GameContent_Add.md @@ -0,0 +1,109 @@ +--- +title: How to add Content to your game +description: Learn how to add content such as images or sounds to your game. +requireMSLicense: true +--- + +> [!TIP] +> For help with creating a project, please look at the [Creating a New Project](~/articles/getting_started/index.md) section of the Getting Started guide. + +## MonoGame Content Builder Tool (MGCB Editor) + +This tutorial assumes that you are using Visual Studio 2022 with its MonoGame extension installed. If you are not using the extension, you will need to manually install and use the [MGCB Editor](~/articles/tools/mgcb_editor.md). + +> [!NOTE] +> This is technically optional, since you can edit the .mgcb files manually if you wish, but the editor is highly recommended for ease of use. + +## Adding content + +First, you will need some content for your game. For this tutorial, use the following image of a ball: + +![Open Content](~/articles/getting_started/images/ball.png) + +Copy the image to your machine by using **right-click > Save Image As** and save it somewhere locally with the name “ball.png”. + +Now open up your game project and look at the Solution Explorer window. Expand the **Content** folder and open up **Content.mgcb** file by double-clicking on it. + +![Open Content](~/articles/getting_started/images/3_open_content.png) + +You should now see the MGCB Editor window open up. If a text file opens instead, then right-click on **Content.mgcb** and select **Open With**, then select **MGCB Editor** in the list, click **Set as Default** and then click **OK**, then try again. + +> [!NOTE] +> If you do not see the **MGCB Editor** option when you right-click and select **Open With**, then please review the [Tools documentation](~/articles/tools/index.md) for installing the MGCB Editor tool for your operating system. + +![MGCB Editor](~/articles/getting_started/images/3_mgcb_editor_tool.png) + +Your game content is managed from this external tool. You can add content to your game in one of the following ways: + +- **Add Existing Item** toolbar button +- **Edit > Add > Existing Item...** menu button +- **right-click > Add > Existing Item...** context menu + +Make sure the `Content` MGCB file is selected to the left, then click the **Add Existing Item** toolbar button. + +![Add Content](~/articles/getting_started/images/3_add_content.png) + +You should now be prompted to select a file. Select the “**ball.png**” image that you downloaded a moment ago. Once you have confirmed your selection, you will be asked whether to copy the file, add a link to it, or skip it. Make sure "**Copy the file to the directory**" option is selected and click **Add**. + +![Copy Content](~/articles/getting_started/images/3_copy_content.png) + +Now click the **Save** toolbar button and close the MGCB Editor tool. + +![Save Content](~/articles/getting_started/images/3_save_content.png) + +--- + +## Adding the content in your game + +Now that you have added the asset to the Content project, it is time to load it into your game. First, open up the `Game1.cs` class file and declare a new `ballTexture` variable of type `Texture2D` in the `Game1` class, so you can store the ball image into memory. + +```csharp +public class Game1 : Game +{ + Texture2D ballTexture; + + private GraphicsDeviceManager _graphics; + private SpriteBatch _spriteBatch; +``` + +Next, find the `LoadContent` method. Here, use [Content.Load()](xref:Microsoft.Xna.Framework.Content.ContentManager#Microsoft_Xna_Framework_Content_ContentManager_Load__1_System_String_) function to load the "ball" sprite and store it in the `ballTexture` parameter. `Content.Load()` requires you to specify what type of content you are trying to load, in this case it is a `Texture2D`. + +```csharp +protected override void LoadContent() +{ + // Create a new SpriteBatch, which can be used to draw textures. + _spriteBatch = new SpriteBatch(GraphicsDevice); + + // TODO: use this.Content to load your game content here + ballTexture = Content.Load("ball"); +} +``` + +Finally, find the Draw method to draw the ball onto the screen. This is done by: + +- Opening a SpriteBatch (an image drawing collection function). +- Adding the images you want to draw and specifying where you want to draw them. +- Then finally closing the SpriteBatch to commit the textures you want drawn to the screen. + +> [!NOTE] +> If you add multiple images, they will be drawn in the order you place them from back to front (each drawn on top of each other). + +As shown below: + +```csharp +protected override void Draw(GameTime gameTime) +{ + graphics.GraphicsDevice.Clear(Color.CornflowerBlue); + + // TODO: Add your drawing code here + _spriteBatch.Begin(); + _spriteBatch.Draw(ballTexture, new Vector2(0, 0), Color.White); + _spriteBatch.End(); + + base.Draw(gameTime); +} +``` + +Now run the game. You should get the following: + +![Game](~/articles/getting_started/images/3_game.png) diff --git a/articles/monogame/howto/content_pipeline/HowTo_GenerateCustomXML.md b/articles/monogame/howto/content_pipeline/HowTo_GenerateCustomXML.md new file mode 100644 index 0000000..304836f --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_GenerateCustomXML.md @@ -0,0 +1,116 @@ +--- +title: How to create a custom XML File? +description: For complex game data, using a software tool to create and maintain these assets may be useful. Level tables, for example, might be easier to develop through a custom-level editor tool. +requireMSLicense: true +--- + +The [IntermediateSerializer](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) class of the MonoGame Framework can be employed by custom tools running under Windows to directly serialize game data to an XML file. + +An XML file generated in this way then can be included in the game project and imported by [XmlImporter Class](xref:Microsoft.Xna.Framework.Content.Pipeline.XmlImporter) as part of the Content Pipeline. Because [XmlImporter](xref:Microsoft.Xna.Framework.Content.Pipeline.XmlImporter) is actually a wrapper for [IntermediateSerializer](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer), it is certain that the XML file will be in the [correct format](../../whatis/Content_Pipeline/CP_XML_Elements.md) to be deserialized by the same facility. + +The [IntermediateSerializer](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) class is controlled through the `XmlWriter` class of the .NET Framework defined in `System.Xml`. The properties of the `XmlWriterSettings` class can be used to specify its output properties. + +The serializer produces its output according to these rules: + +- All public fields and properties are serialized; a separate XML element is used for each. +- Protected, private, or internal data is skipped. +- Get-only or set-only properties are skipped. +- Properties come before fields. +- If there is more than one field or property, these are serialized in the order they are declared. +- Nested types are serialized using nested XML elements. +- When the class derives from another, members of the base class are serialized before data from the derived type. + +## XML Serialization Example + +The following steps create a simple program that demonstrates how a program can use the [IntermediateSerializer](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) method [IntermediateSerializer.Serialize Generic Method](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) to serialize program data to an XML file. + +### Step 1: Create a New Project + +You will create a new project in Visual Studio. + +1. On the `File` menu, click `New`, and then click `Project`. + +2. In the `New Project` dialog box, ensure `Windows` is selected in the `Project types` pane, and then click `Console Application` in the `Templates` pane. + +3. Open the new project, then in the `Solution Explorer`, right-click the `Dependencies` folder, and then click `Manage NuGet Packages..`. + +4. Click on the `Browse` tab (if not selected) and search for the `MonoGame.Framework.Content.Pipeline` package, and then click `Install`. + + Accept any dialog prompts for Licenses or dependencies as they appear. + +5. Additionally, install the `MonoGame.Framework.DesktopGL` NuGet package which is required by the `Content.Pipeline` package. + +## Step 2: Add XML Serialization + +1. In the `Solution Explorer`, double-click `Program.cs` to edit it. + +2. Add `using` declarations for the System.Xml and Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate namespaces. + + ```csharp + using System.Xml; + using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate; + ``` + +3. Define a class to serialize to XML with the properties you wish to store in your custom XML. + + ```csharp + namespace XMLSerializerTest + { + class MyData + { + public int elf = 23; + public string hello = "Hello World"; + } + } + ``` + +4. Within the function `Main` of the `Program` class, add the following code. This code employs [IntermediateSerializer.Serialize Generic Method](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) to serialize the `MyData` class as an XML file. + +```csharp + class Program + { + static void Main(string[] args) + { + MyData ExampleData = new MyData(); + + XmlWriterSettings settings = new XmlWriterSettings(); + settings.Indent = true; + + using (XmlWriter writer = XmlWriter.Create("example.xml", settings)) + { + IntermediateSerializer.Serialize(writer, ExampleData, null); + } + } + } +``` + +## Step 3: Generate XML + +1. Press F5 to build and execute the program. +2. Examine the `example.xml` file in the project's `bin\\Debug\\netx.0` folder. + +> [!NOTE] +> `netx.0` relates to the version of .NET your project is building under, `net6.0` for `.NET 6` and `net8.0` for `.NET 8` + +You should have an output that looks like the following: + +```xml + + + + 23 + Hello World + + +``` + +## See Also + +### Concepts + +- [Using an XML File to Specify Content](HowTo_UseCustomXML.md) +- [Adding Content to a Game](HowTo_GameContent_Add.md) + +## Reference + +- [IntermediateSerializer Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) diff --git a/articles/monogame/howto/content_pipeline/HowTo_LoadContentLibrary.md b/articles/monogame/howto/content_pipeline/HowTo_LoadContentLibrary.md new file mode 100644 index 0000000..0dcd01e --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_LoadContentLibrary.md @@ -0,0 +1,122 @@ +--- +title: How to load content within a Game Library? +description: It may be desirable in some designs to load and draw content within the methods of a Game Library. For example, you may wish to distribute code that displays textures, models, or fonts (such as a DrawableGameComponent) in a .DLL. +requireMSLicense: true +--- + +There are two advanced techniques that accommodate this, one in which the binary content is separate from the .DLL, and one in which the content is embedded within the .DLL. + +- [Loading Content in a custom Game Library](#loading-content-in-a-custom-game-library) +- [Embedding Content in a Game Library](#embedding-content-in-a-game-library) + +## Loading Content in a custom Game Library + +In this method, the compiled content used by the game library is distributed in its own .xnb files, separate from the .DLL. + +This is the preferred method in most cases, as it makes the most efficient use of memory, especially when binary content is large. + +### To create compiled content + +1. Create a new solution that contains a game library project. +2. [Add a game content project](HowTo_GameContent_Add.md) to the solution. +3. In a library project, choose **Add, New Item**, and select "Resources File." +4. Select the game library project, then right-click and choose **Add Content Reference...**, and select the game content project you just created. + +When the solution is built, the resources in the content project will be compiled into binary .xnb files. These files will reside in the "bin\\x86\\Debug\\Content" directory of the game library project (if built as an x86 debug project). + +### To load compiled content within the Game Library + +1. Create a new class that is the child of [DrawableGameComponent](xref:Microsoft.Xna.Framework.DrawableGameComponent). +2. Define a new [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager) and, within the constructor of the new class, set its **RootDirectory** to the path where the compiled content is to be stored. + + For flexibility, the path string may be a parameter passed to the constructor by the game client. + + ```csharp + public static ContentManager LibContent; + + public GameLibComponent(Game game, string contentdirectory) : base(game) + { + LibContent = new ContentManager(game.Services); + LibContent.RootDirectory = contentdirectory; + } + ``` + +3. In the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) method, load your content normally using your [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager). + + ```csharp + SpriteBatch spriteBatch; + Texture2D LibTexture; + + protected override void LoadContent() + { + spriteBatch = new SpriteBatch(GraphicsDevice); + LibTexture = LibContent.Load("mytexture"); + } + ``` + +## Embedding Content in a Game Library + +You may also embed binary content resources directly in the Game Library and load them from within. This technique requires the declaration of those resources in a reference file. It allows you to distribute code that displays textures, models, or fonts (such as a [DrawableGameComponent](xref:Microsoft.Xna.Framework.DrawableGameComponent)) in a .DLL without distributing the .xnb files separately. + +> **Note** +> +> Be aware that all embedded resources are loaded into memory with the .DLL, and cannot be unloaded from main memory. For this reason, this technique is not recommended for most applications, and should only be used when the content to embed is very small. + +### To add content to a Game Library as references + +1. Build an existing project containing the content you wish to add. +2. In a library project, choose **Add**, **New Item**, and select "Resources File". +3. If the **Resource Designer** is not opened automatically, double-click the .resx file in the **Solution Explorer**. +4. From the **Resource Designer**, choose **Add Resource**, **Add Existing File**. +5. Navigate to the "bin\\x86\\Debug\\Content" directory of the project that built the content you wish to add. + + > This assumes it was built as an x86 Debug project. + +6. Select the .xnb files for the content you wish to add to the library. + + > Ensure the dialog box is displaying "All Files". + +Once content has been added to the **Resource Designer**, any code running from within the Library can load the content with a special [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager). + +### To load embedded content within a Game Library + +1. Create a new class that is the child of [DrawableGameComponent](xref:Microsoft.Xna.Framework.DrawableGameComponent). +2. Define a new [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager). +3. Within the constructor of the new class, create a new instance of the [ResourceContentManager](xref:Microsoft.Xna.Framework.Content.ResourceContentManager) class and assign it to your [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager). + + The second parameter to the [ResourceContentManager](xref:Microsoft.Xna.Framework.Content.ResourceContentManager) constructor identifies the resource project that contains your embedded resources. + + ```csharp + public static ContentManager LibContent; + + public GameLibComponent(Game game) + : base(game) + { + ResourceContentManager resxContent; + resxContent = new ResourceContentManager(game.Services, ResourceFile.ResourceManager); + LibContent = resxContent; + } + ``` + +4. In the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) method, load your content normally using your [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager). + + ```csharp + SpriteBatch spriteBatch; + Texture2D LibTexture; + + protected override void LoadContent() + { + spriteBatch = new SpriteBatch(GraphicsDevice); + LibTexture = LibContent.Load("mytexture"); + } + ``` + +## See Also + +### Reference + +- [Game Class](xref:Microsoft.Xna.Framework.Game) +- [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) +- [UnloadContent](xref:Microsoft.Xna.Framework.Game.UnloadContent) +- [Game Members](xref:Microsoft.Xna.Framework.Game) +- [Microsoft.Xna.Framework Namespace](xref:Microsoft.Xna.Framework) diff --git a/articles/monogame/howto/content_pipeline/HowTo_Load_XML.md b/articles/monogame/howto/content_pipeline/HowTo_Load_XML.md new file mode 100644 index 0000000..c1f6c10 --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_Load_XML.md @@ -0,0 +1,89 @@ +--- +title: How to load XML Content at Runtime? +description: Describes how to load custom game data at game runtime through the Content Pipeline. +requireMSLicense: true +--- + +This example concludes the procedure begun in the tutorial [Adding an XML Content File to a Visual Studio Project](HowTo_Add_XML.md). + +Once custom game data is integrated as game content from an XML file through the Content Pipeline, it exists within your game runtime package in binary format. The data can be [loaded at runtime](HowTo_GameContent_Add.md) through the [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager). + +## Add a SpriteFont for testing + +While not essential for loading XML, in order to demonstrate the loaded data and write it to the screen, we will add a [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) to enable the drawing of strings. + +1. In the `Solution Explorer`, Double-click the `Content.mgcb` in the `Content` folder to open the MGCB editor. + + > [!TIP] + > If you have any issues opening the MGCB content project, please refer to the [How to load content](HowTo_GameContent_Add.md) guide. + +2. Click on `Edit -> New Item`, then name the file `Font` and select `SpriteFont Description` as the type. Click on `Create` to finish. + +3. Save the content project and then continue. + +## To load the custom data in the game + +1. To add the `MyDataTypes` library as a reference in the game project, In the `Solution Explorer`, right-click the game project, click `Add Reference`, click the `Projects` tab, select `MyDataTypes`, and then click `OK`. + +2. Then in the `Solution Explorer`, double-click `Game1.cs` to edit it. + +3. Add the `using` declaration for the MyDataTypes namespace at the top of the file beneath the existing `usings` statements. + + ```csharp + using MyDataTypes; + ``` + +4. Add a data declaration for an array of type `PetData` after the other `private` variables in the `Game1` class. + + ```csharp + private PetData[] pets; + ``` + +5. In the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) override function, load the custom content. + + ```csharp + protected override void LoadContent() + { + // Load the pet data table + pets = Content.Load("pets"); + } + ``` + + The custom game data now resides in the array of `PetData` objects. + +6. The data loaded from the XML file into the `PetData` array can be accessed normally as c# code, for example, the following `Draw` code will render the data from the XML file to the screen if found, else it will write a warning. + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + _spriteBatch.Begin(); + // Check if the XML data was loaded into the pets data array. + if (pets != null) + { + // For each pet, write its data to the screen. + for (int i = 0; i < pets.Length; i++) + { + var pet = pets[i]; + _spriteBatch.DrawString(Content.Load("Font"), $"{pet.Name} / {pet.Species}: Weight [{pet.Weight}] - Age: [{pet.Age}]", new Vector2(100, 100 + 20 * i), Color.White); + } + } + else + { + // If no data was loaded (or there was an error) write `No Pets found` to the screen. + _spriteBatch.DrawString(Content.Load("Font"), "No pets found", new Vector2(100, 100), Color.White); + } + _spriteBatch.End(); + base.Draw(gameTime); + } + ``` + +The result of loading the XML and rendering the data should display as follows: + +![XML data output](../images/HowTo_Load_XML_Final.png) + +## See Also + +- [Using an XML File to Specify Content](HowTo_UseCustomXML.md) +- [Adding Content to a Game](HowTo_GameContent_Add.md) diff --git a/articles/monogame/howto/content_pipeline/HowTo_Localize_Content.md b/articles/monogame/howto/content_pipeline/HowTo_Localize_Content.md new file mode 100644 index 0000000..6fa3213 --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_Localize_Content.md @@ -0,0 +1,216 @@ +--- +title: How to create a Localized Game? +description: A localized game is one in which the UI displays alternative sets of text that are appropriate to the language and culture of the gamer. +requireMSLicense: true +--- + +This tutorial demonstrates methods that allow a game to display differing UI text according to the platform's current culture setting stored in [CultureInfo](http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx). It also demonstrates how to extend the Content Pipeline so that the minimum number of additionally required font characters are included in the game executable for the localized text. + +For more detailed information about both globalization and localization issues for Windows Phone, see [Globalization and Localization for Windows Phone](http://go.microsoft.com/fwlink/?LinkId=254839) in the Windows Phone documentation. + +- [Creating Resource Files](#creating-resource-files) +- [Extending the Content Pipeline](#extending-the-content-pipeline) +- [Associating Localization Data and Processors With Fonts](#associating-localization-data-and-processors-with-fonts) +- [Using Localized Strings in the Game](#using-localized-strings-in-the-game) + +## Creating Resource Files + +A localized game should maintain its resources in resource (.resx) files in the game's code project. The game should maintain at least one resource file for every language/culture it is to support. Each resource file defines identifiers for each localizable UI string in the game, with a localized version of that string for the intended language/culture. In this way, localization can be maintained independently from coding. + +### To create resource files + +1. In **Solution Explorer**, right-click the code project node, select **Add**, and then click **New Item**. + +2. In the **Add New Item** dialog box, select the resources file, and rename it as appropriate, for example, Strings.resx. + + This file will contain the resources for the default language for the application. + +3. Identify strings in your application and add them to the resource file. + + Each string has a name, a value, and an optional comment. The name must be unique so make it as descriptive as possible. The value is the string to be displayed in the application to the user. Adding a comment is useful, especially in large resource files as a reminder of the purpose of the string and later as information for the translator to understand the correct context. + + **Figure 1.  An example of English language strings for the Strings.resx resource file** + + ![English language strings](../images/CP_HowTo_Localize_Strings.png) + +4. Add a new resource file to your project for each language/culture the application will support. + + > **Note** + > + > Each resource file must follow the naming convention: + > + > _name of the resource file for the default language_._culture name_ + > + > An example of this format is MyStrings.fr.resx, where the culture name—fr in this instance—is derived from the [CultureInfo](http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx) class. + + As shown in the next figure, the strings defined for the resource file must have the same set of identifying names as defined in the default resource file. + + **Figure 2.   An example of French language strings for the resource file Strings.fr.resx** + + ![French language strings](../images/CP_HowTo_Localize_Strings_fr.png) + + **Figure 3.  An example of strings in the Japanese language resource file Strings.ja.resx** + + ![Japanese language strings](../images/CP_HowTo_Localize_Strings_ja.png) + +> **Note** +> +> Universal Windows Applications Specific Information +> +> Universal Windows Applications (UWP) do not use `resx` files. These have been replace with `resw` files, the format is slightly different but the process is the same as `resx`. It does however mean you need to maintain two copies of the language files when targeting UWP and other platforms. + +## Extending the Content Pipeline + +To accommodate a localized game, you need to create a new Content Pipeline Library Extension project to process the resource files and fonts. + +The new content library extension must extend the [FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription) class to support a list of the resource files that later will be included in the .spritefont file. + +You also will need to create a new content processor that extends [FontDescriptionProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontDescriptionProcessor) to process the resource file list, and to include the required characters in the built game executable. + +### To create a Content Pipeline Extension Library project + +1. On the File menu, click New Project. +2. Select the Content Pipeline Extension Library (4.0) project type. +3. In the Name box, type the name for the new library project. +4. You might name the project LocalizationPipeline for example. +5. Click OK to create and load the new project. + +### To extend the FontDescriptor class + +You will add a new file to contain the new class. + +1. In Solution Explorer, right-click the newly created Content Pipeline Library Extension project, select Add, click New Item, and then select Class. + + Assign the new file a name such as LocalizedFontDescription.cs. + +2. In the new class file, declare a new class (for example, LocalizedFontDescription) that derives from [FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription). + + ```csharp + class LocalizedFontDescription : FontDescription + ``` + +3. Within the class, define a new ResourceFiles property. + + This action results in recognition of a ResourceFiles element in the .spritefont XML file, which will contain the list of resource files. + + ```csharp + [ContentSerializer(Optional = true, CollectionItemName = "Resx")] + public List ResourceFiles + { + get { return resourceFiles; } + } + + List resourceFiles = new List(); + ``` + +### To extend the FontDescriptionProcessor class + +A new file to contain the new FontDescriptionProcessor class will be added. + +1. In Solution Explorer, right-click the content pipeline extension project, select Add, click New Item, and then select Class. + + Assign the new file a name, such as LocalizedFontProcessor.cs. + +2. In the new class file, declare a new class (for example, LocalizedFontProcessor) that derives from [ContentProcessor](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor-2.html), and specifies the new LocalizedFontDescription class as input. + + ```csharp + [ContentProcessor] + class LocalizedFontProcessor : ContentProcessor + ``` + + Within the class, override the **Process** method with the new LocalizedFontDescription class as input. + + ```csharp + public override SpriteFontContent Process(LocalizedFontDescription input, ContentProcessorContext context) + ``` + +3. In the new **Process** method, step through the ResourceFiles property of the LocalizedFontDescription object to load each declared resource file. + + ```csharp + foreach (string resourceFile in input.ResourceFiles) + { + string absolutePath = Path.GetFullPath(resourceFile); + + // Make sure the .resx file really does exist. + if (!File.Exists(absolutePath)) + { + throw new InvalidContentException("Can't find " + absolutePath); + } + + // Load the .resx data. + XmlDocument xmlDocument = new XmlDocument(); + + xmlDocument.Load(absolutePath); + ``` + +4. For each resource file, scan each string and add found characters to the LocalizedFontDescription object. + + ```csharp + // Scan each string from the .resx file. + foreach (XmlNode xmlNode in xmlDocument.SelectNodes("root/data/value")) + { + string resourceString = xmlNode.InnerText; + + // Scan each character of the string. + foreach (char usedCharacter in resourceString) + { + input.Characters.Add(usedCharacter); + } + } + ``` + +5. Using **AddDependency**, mark that the font should be rebuilt if the resource file changes. + + ```csharp + context.AddDependency(absolutePath); + ``` + +6. Use the [FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription) class to build the font. + +## Associating Localization Data and Processors With Fonts + +Now that project data is divided into resource files, and has a custom content processor to consume it, the parts need to be bound together to help them work. This is accomplished by providing extended information in a `.spritefont` file, and binding the file to the custom content processor. + +### To extend the .spritefont file + +Create a new `.spritefont` file. + +1. In **Pipeline Tool**, right-click the content project node, select **Add**, and then click **New Item**. +2. In the **Add New Item** dialog box, select "Localized Sprite Font," and then in the **Name** box, enter a name (for example, `Font.spritefont`) for the new file. +3. Click **Add** to create the new file. This will create a new Localized Sprite Font which is already setup to work with localized resource files. +4. Right Click on the new file and select Open or Open With to open it for editing. +5. Change the asset type declaration to reference the previously created extended FontDescriptor class. + + ```xml + + ``` + +6. Add a block within `` tags that lists each resource file using the `` elements. + The example tags below specify resource files for the default language, as well as for Danish (da), French (fr), Japanese (ja), and Korean (ko). + + ```xml + + ..\\Strings.resx + ..\\Strings.da.resx + ..\\Strings.fr.resx + `..\\Strings.ja.resx + `..\\Strings.ko.resx + + ``` + +7. Save the file. + +## Using Localized Strings in the Game + +The localized strings will be available in your game as a class with the same name as the base file name of the resource file for the default language (for example, Strings). + +Setting the **Culture** property of this class from the [CultureInfo.CurrentCulture](http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.currentculture.aspx) property will cause the correct language version of the localized strings to be loaded according to the platform's current culture setting. + +```csharp + Strings.Culture = CultureInfo.CurrentCulture; +``` + +## See Also + +- [Extending a Standard Content Processor](./HowTo_Extend_Processor.md) +- [Adding New Content Types](../../whatis/Content_Pipeline/CP_Content_Advanced.md) diff --git a/articles/monogame/howto/content_pipeline/HowTo_UseCustomXML.md b/articles/monogame/howto/content_pipeline/HowTo_UseCustomXML.md new file mode 100644 index 0000000..119cb08 --- /dev/null +++ b/articles/monogame/howto/content_pipeline/HowTo_UseCustomXML.md @@ -0,0 +1,41 @@ +--- +title: How to use an XML File to Specify Content? +description: Game assets managed through the Content Pipeline include graphic items such as textures, models and meshes; sound files such as dialogue or music; and custom data that governs the behavior of the game. +requireMSLicense: true +--- + +Data tables, for example, are custom data that might describe different characters’ attributes or the features of each level in the game. The content and format of this data is specific to the requirements of the game. Custom game data in the form of an XML file also can be loaded into your game through the standard features of the Content Pipeline. + +When the Content Pipeline is used, the game does not have to parse the XML format in which the game data is originally stored. Data loaded by the game through [ContentManager](xref:Microsoft.Xna.Framework.Content.ContentManager) is read in deserialized form directly into a managed code object. + +## In This Section + +- [How to Add custom game data as an XML file](HowTo_Add_XML.md) + + Describes how to add custom game data as an XML file through the Content Pipeline. + +- [Generating a custom XML File](HowTo_GenerateCustomXML.md) + + Describes how to use [IntermediateSerializer](xref:Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer) from a Windows application to generate XML content to add to a MonoGame application. + +- [Adding an XML Content File to a MonoGame Project](HowTo_GameContent_Add.md) + + Describes how to add custom game data as an XML file through the Content Pipeline. + +- [Loading XML Content at Runtime](HowTo_Load_XML.md) + + Describes how to load custom game data at game runtime through the Content Pipeline. + +- [XML Elements for XMLImporter](../../whatis/Content_Pipeline/CP_XML_Elements.md) + + Describes the elements of an XML file that can be processed by the [XmlImporter Class](xref:Microsoft.Xna.Framework.Content.Pipeline.XmlImporter). + +- [Sprite Font XML Schema Reference](../../whatis/Content_Pipeline/CP_SpriteFontSchema.md) + + Describes the valid tags and values for Sprite-Font (.spritefont) XML files used by the Content Pipeline to create [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) textures. + +## See Also + +### Concepts + +[Adding Content to a Game](./HowTo_GameContent_Add.md) diff --git a/articles/monogame/howto/content_pipeline/index.md b/articles/monogame/howto/content_pipeline/index.md new file mode 100644 index 0000000..137f5b2 --- /dev/null +++ b/articles/monogame/howto/content_pipeline/index.md @@ -0,0 +1,31 @@ +--- +title: How To articles for the Content Pipeline +description: A series of articles to answer common questions related to Content Pipeline operation! +requireMSLicense: true +--- + +## In This Section + +- [How to add content](HowTo_GameContent_Add.md) + + Demonstrates how to add content, such as images or sounds, to your game. + +- [How to use custom XML](HowTo_UseCustomXML.md) + + Demonstrates how to use a custom XML File to Specify Content. + +- [How to Load content from a library](HowTo_LoadContentLibrary.md) + + Demonstrates how to create A localized game using alternative sets of text that are appropriate to the language and culture of the gamer. + +- [How to extend a content processor](HowTo_Extend_Processor.md) + + Describes how MonoGame lets you modify or extend the behavior of any standard Content Pipeline processor. + +- [How to Extend the Font Description Processor to Support Additional Characters](HowTo_ExtendFontProcessor.md) + + Describes the process of developing a custom content processor needed to add additional characters to a [FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription) object based on the text that is required by the game. + +- [How to Create a Localized Game](HowTo_Localize_Content.md) + + Demonstrates how to create A localized game using alternative sets of text that are appropriate to the language and culture of the gamer. diff --git a/articles/monogame/howto/content_pipeline/toc.yml b/articles/monogame/howto/content_pipeline/toc.yml new file mode 100644 index 0000000..88d1823 --- /dev/null +++ b/articles/monogame/howto/content_pipeline/toc.yml @@ -0,0 +1,23 @@ +- name: Introduction + href: index.md +- name: How to add content + href: HowTo_GameContent_Add.md +- name: Loading Custom XML + href: HowTo_UseCustomXML.md + items: + - name: How to Add custom XML + href: HowTo_Add_XML.md + - name: How to Load custom XML + href: HowTo_Load_XML.md + - name: How to generate custom XML + href: HowTo_GenerateCustomXML.md +- name: How to load a content Library + href: HowTo_LoadContentLibrary.md +- name: Extending Content Processors + items: + - name: How to extend a content processor + href: HowTo_Extend_Processor.md + - name: How to extend a font processor + href: HowTo_ExtendFontProcessor.md +- name: How to localize content + href: HowTo_Localize_Content.md diff --git a/articles/monogame/howto/graphics/HowTo_Animate_Sprite.md b/articles/monogame/howto/graphics/HowTo_Animate_Sprite.md new file mode 100644 index 0000000..0b33adc --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Animate_Sprite.md @@ -0,0 +1,139 @@ +--- +title: Animating a Sprite +description: Demonstrates how to animate a sprite from a texture using a custom class. +--- + +# Animating a Sprite + +Demonstrates how to animate a sprite from a texture using a custom class. + +The example assumes the texture you are loading contains four frames of the same size in a texture whose size is 256×64 pixels, and uses a class named **AnimatedTexture**, which is included with the sample. + +## Drawing an Animated Sprite + +1. In your game's constructor, create an instance of the **AnimatedTexture** class. + This example uses (0,0) as the origin of the texture, no rotation, a scale of 2, and a depth of 0.5. + + ```csharp + private AnimatedTexture SpriteTexture; + private const float Rotation = 0; + private const float Scale = 2.0f; + private const float Depth = 0.5f; + public Game1() + { + ... + SpriteTexture = new AnimatedTexture(Vector2.Zero, Rotation, Scale, Depth); + + // Set device frame rate to 30 fps. + TargetElapsedTime = TimeSpan.FromSeconds(1 / 30.0); + } + ``` + +2. Load one or more textures to provide the image data for the animation. + In this example, the **AnimatedTexture** class loads a single texture and divides it into frames of animation. It uses the last parameter to determine how many frames to draw each second. In this case, it draws four frames at two frames per second (fps). + + ```csharp + private Viewport viewport; + private Vector2 shipPos; + private const int Frames = 4; + private const int FramesPerSec = 2; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + // "shipanimated" is the name of the sprite asset in the project. + SpriteTexture.Load(Content, "shipanimated", Frames, FramesPerSec); + viewport = graphics.GraphicsDevice.Viewport; + shipPos = new Vector2(viewport.Width / 2, viewport.Height / 2); + } + ``` + +3. In your game's [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method, determine which animation frame to display. + + ```csharp + protected override void Update(GameTime gameTime) + { + ... + float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; + + // TODO: Add your game logic here. + SpriteTexture.UpdateFrame(elapsed); + base.Update(gameTime); + } + ``` + + This is handled by AnimatedTexture's **UpdateFrame** method, which takes the elapsed seconds between updates as a parameter. + + ```csharp + // class AnimatedTexture + public void UpdateFrame(float elapsed) + { + if (Paused) + return; + TotalElapsed += elapsed; + if (TotalElapsed > TimePerFrame) + { + Frame++; + // Keep the Frame between 0 and the total frames, minus one. + Frame = Frame % framecount; + TotalElapsed -= TimePerFrame; + } + } + ``` + +4. In your game's [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, call [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) on the **AnimatedTexture** object. + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + // TODO: Add your drawing code here + spriteBatch.Begin(); + SpriteTexture.DrawFrame(spriteBatch, shipPos); + spriteBatch.End(); + + base.Draw(gameTime); + } + ``` + + **AnimatedTexture** draws the sprite using the subrectangle of the texture that contains the desired animation. + + ```csharp + // class AnimatedTexture + public void DrawFrame(SpriteBatch batch, Vector2 screenPos) + { + DrawFrame(batch, Frame, screenPos); + } + public void DrawFrame(SpriteBatch batch, int frame, Vector2 screenPos) + { + int FrameWidth = myTexture.Width / framecount; + Rectangle sourcerect = new Rectangle(FrameWidth * frame, 0, + FrameWidth, myTexture.Height); + batch.Draw(myTexture, screenPos, sourcerect, Color.White, + Rotation, Origin, Scale, SpriteEffects.None, Depth); + } + ``` + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_AspectRatio.md b/articles/monogame/howto/graphics/HowTo_AspectRatio.md new file mode 100644 index 0000000..97fbe68 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_AspectRatio.md @@ -0,0 +1,124 @@ +--- +title: How to restrict Aspect Ratio on a Graphics Device +description: Demonstrates how to create a custom GraphicsDeviceManager that only selects graphics devices with widescreen aspect ratios in full-screen mode. +--- + +# Restricting Aspect Ratio on a Graphics Device + +Demonstrates how to create a custom [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) that only selects graphics devices with widescreen aspect ratios in full-screen mode. + +## Restricting Graphics Devices + +### To restrict graphics devices to widescreen aspect ratios in full-screen mode + +1. Create a class that derives from [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager). + + ```csharp + public class CustomGraphicsDeviceManager : GraphicsDeviceManager + { + public CustomGraphicsDeviceManager( Game game ) + : base( game ) + { + } + + } + ``` + +2. Add a **WideScreenOnly** property to the class. + + The property is used to turn on and off the widescreen-only behavior. + + ```csharp + private bool isWideScreenOnly; + public bool IsWideScreenOnly + { + get { return isWideScreenOnly; } + set { isWideScreenOnly = value; } + } + ``` + +3. Determine the minimum desired aspect ratio. + + ```csharp + static float WideScreenRatio = 1.6f; //1.77777779f; + ``` + +4. Override the **RankDevices** method of [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager). + + Note the call to [base.RankDevices](xref:Microsoft.Xna.Framework.GraphicsDeviceManager). This call ensures that the new version of **RankDevices** has an already ranked list of available devices with which to work. + + ```csharp + protected override void RankDevices( + List foundDevices ) + { + base.RankDevices( foundDevices ); + } + ``` + +5. Add a check to see if the **WideScreenOnly** property is **true**. + + ```csharp + if (IsWideScreenOnly) + { + ... + } + ``` + +6. In the **if** block, loop through all found devices, and check whether the [PresentationParameters](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters) indicate the device is full-screen. + +7. If the device is full-screen, determine the aspect ratio of the device by dividing the **BackBufferWidth** by the **BackBufferHeight**. + +8. If the aspect ratio is less than the desired aspect ratio, remove the device from the list of found devices. + + ```csharp + for (int i = 0; i < foundDevices.Count; ) + { + PresentationParameters pp = + foundDevices[i].PresentationParameters; + if (pp.IsFullScreen == true) + { + float aspectRatio = (float)(pp.BackBufferWidth) / + (float)(pp.BackBufferHeight); + + // If the device does not have a widescreen aspect + // ratio, remove it. + if (aspectRatio < WideScreenRatio) + { + foundDevices.RemoveAt( i ); + } + else { i++; } + } + else i++; + } + ``` + +9. Replace the default [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) with the derived [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager). +10. To test the new component, set the **WideScreenOnly** and **IsFullScreen** properties to **true**. + + ```csharp + public Game1() + { + graphics = new CustomGraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + + this.graphics.PreferMultiSampling = false; + #if WINDOWS + this.graphics.PreferredBackBufferWidth = 1280; + this.graphics.PreferredBackBufferHeight = 720; + #endif + #if WINDOWS_PHONE + this.graphics.PreferredBackBufferWidth = 400; + this.graphics.PreferredBackBufferHeight = 600; + #endif + + this.graphics.IsFullScreen = true; + this.graphics.IsWideScreenOnly = true; + graphics.ApplyChanges(); + } + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Create_a_BasicEffect.md b/articles/monogame/howto/graphics/HowTo_Create_a_BasicEffect.md new file mode 100644 index 0000000..815da2f --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Create_a_BasicEffect.md @@ -0,0 +1,192 @@ +--- +title: How to create a Basic Effect +description: The basics of the 3D rendering pipeline for MonoGame! +--- + +# How to create a Basic Effect + +Demonstrates how to create and initialize an instance of the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class and use it to draw simple geometry. + +> The steps described here apply to effects created with the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class. Use the [Effect](xref:Microsoft.Xna.Framework.Graphics.Effect) class to write a custom effect. The example draws aliased geometry. To see an example that draws smoother edges because it also applies anti-aliasing, see [Enabling Anti-aliasing (Multi-sampling)](HowTo_Enable_Anti_Aliasing.md). + +## Using BasicEffect + +### To use BasicEffect + +Using the basic effect class requires a set of world, view, and projection matrices, a vertex buffer, a vertex declaration, and an instance of the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class. + +1. Declare these objects at the beginning of the game. + + ```csharp + Matrix worldMatrix; + Matrix viewMatrix; + Matrix projectionMatrix; + VertexPositionNormalTexture[] cubeVertices; + VertexDeclaration vertexDeclaration; + VertexBuffer vertexBuffer; + BasicEffect basicEffect; + ``` + +2. Initialize the world, view, and projection matrices. + + In this example, you create a world matrix that rotates the geometry 22.5 degrees along the x and y axes. The view matrix is a look-at matrix with a camera position at (0, 0, 5), pointing at the origin. The projection matrix is a perspective projection matrix based on a a 45-degree field of view, an aspect ratio equal to the client window, and a set of near and far planes. + + ```csharp + float tilt = MathHelper.ToRadians(0); // 0 degree angle + // Use the world matrix to tilt the cube along x and y axes. + worldMatrix = Matrix.CreateRotationX(tilt) * Matrix.CreateRotationY(tilt); + viewMatrix = Matrix.CreateLookAt(new Vector3(5, 5, 5), Vector3.Zero, Vector3.Up); + + projectionMatrix = Matrix.CreatePerspectiveFieldOfView( + MathHelper.ToRadians(45), // 45 degree angle + (float)GraphicsDevice.Viewport.Width / + (float)GraphicsDevice.Viewport.Height, + 1.0f, 100.0f); + ``` + +3. Initialize [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) with transformation and light values. + + ```csharp + basicEffect = new BasicEffect(graphics.GraphicsDevice); + + basicEffect.World = worldMatrix; + basicEffect.View = viewMatrix; + basicEffect.Projection = projectionMatrix; + + // primitive color + basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f); + basicEffect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f); + basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f); + basicEffect.SpecularPower = 5.0f; + basicEffect.Alpha = 1.0f; + + basicEffect.LightingEnabled = true; + if (basicEffect.LightingEnabled) + { + basicEffect.DirectionalLight0.Enabled = true; // enable each light individually + if (basicEffect.DirectionalLight0.Enabled) + { + // x direction + basicEffect.DirectionalLight0.DiffuseColor = new Vector3(1, 0, 0); // range is 0 to 1 + basicEffect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(-1, 0, 0)); + // points from the light to the origin of the scene + basicEffect.DirectionalLight0.SpecularColor = Vector3.One; + } + + basicEffect.DirectionalLight1.Enabled = true; + if (basicEffect.DirectionalLight1.Enabled) + { + // y direction + basicEffect.DirectionalLight1.DiffuseColor = new Vector3(0, 0.75f, 0); + basicEffect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(0, -1, 0)); + basicEffect.DirectionalLight1.SpecularColor = Vector3.One; + } + + basicEffect.DirectionalLight2.Enabled = true; + if (basicEffect.DirectionalLight2.Enabled) + { + // z direction + basicEffect.DirectionalLight2.DiffuseColor = new Vector3(0, 0, 0.5f); + basicEffect.DirectionalLight2.Direction = Vector3.Normalize(new Vector3(0, 0, -1)); + basicEffect.DirectionalLight2.SpecularColor = Vector3.One; + } + } + ``` + +4. Create a vertex declaration for the type [VertexPositionNormalTexture](xref:Microsoft.Xna.Framework.Graphics.VertexPositionNormalTexture). + + * If lighting is enabled, the vertex must have a normal type. + + * If vertex colors are enabled, the vertex must have colors. + + * If texturing is enabled, the vertex must have a texture coordinate. + + ```csharp + vertexDeclaration = new VertexDeclaration(new VertexElement[] + { + new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), + new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0), + new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0) + } + ); + ``` + +5. Create the per vertex data. This example shows the data for one face of the cube. + + ```csharp + Vector3 topLeftFront = new Vector3(-1.0f, 1.0f, 1.0f); + Vector3 bottomLeftFront = new Vector3(-1.0f, -1.0f, 1.0f); + Vector3 topRightFront = new Vector3(1.0f, 1.0f, 1.0f); + Vector3 bottomRightFront = new Vector3(1.0f, -1.0f, 1.0f); + Vector3 topLeftBack = new Vector3(-1.0f, 1.0f, -1.0f); + Vector3 topRightBack = new Vector3(1.0f, 1.0f, -1.0f); + Vector3 bottomLeftBack = new Vector3(-1.0f, -1.0f, -1.0f); + Vector3 bottomRightBack = new Vector3(1.0f, -1.0f, -1.0f); + + Vector2 textureTopLeft = new Vector2(0.0f, 0.0f); + Vector2 textureTopRight = new Vector2(1.0f, 0.0f); + Vector2 textureBottomLeft = new Vector2(0.0f, 1.0f); + Vector2 textureBottomRight = new Vector2(1.0f, 1.0f); + + Vector3 frontNormal = new Vector3(0.0f, 0.0f, 1.0f); + Vector3 backNormal = new Vector3(0.0f, 0.0f, -1.0f); + Vector3 topNormal = new Vector3(0.0f, 1.0f, 0.0f); + Vector3 bottomNormal = new Vector3(0.0f, -1.0f, 0.0f); + Vector3 leftNormal = new Vector3(-1.0f, 0.0f, 0.0f); + Vector3 rightNormal = new Vector3(1.0f, 0.0f, 0.0f); + + // Front face. + cubeVertices[0] = + new VertexPositionNormalTexture( + topLeftFront, frontNormal, textureTopLeft); + cubeVertices[1] = + new VertexPositionNormalTexture( + bottomLeftFront, frontNormal, textureBottomLeft); + cubeVertices[2] = + new VertexPositionNormalTexture( + topRightFront, frontNormal, textureTopRight); + cubeVertices[3] = + new VertexPositionNormalTexture( + bottomLeftFront, frontNormal, textureBottomLeft); + cubeVertices[4] = + new VertexPositionNormalTexture( + bottomRightFront, frontNormal, textureBottomRight); + cubeVertices[5] = + new VertexPositionNormalTexture( + topRightFront, frontNormal, textureTopRight); + ``` + +6. Call [GraphicsDevice.Clear](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_Clear_Microsoft_Xna_Framework_Color_) to clear the render target. + +7. Set the rasterizer state to turn off culling using the [RasterizerState](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.RasterizerState) property. + +8. Call [EffectPass.Apply](/api/Microsoft.Xna.Framework.Graphics.EffectPass.html#Microsoft_Xna_Framework_Graphics_EffectPass_Apply) to set the effect state in preparation for rendering. + +9. Draw the geometry by calling [GraphicsDevice.DrawPrimitives](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawPrimitives_Microsoft_Xna_Framework_Graphics_PrimitiveType_System_Int32_System_Int32_). + + ```csharp + graphics.GraphicsDevice.Clear(Color.SteelBlue); + + RasterizerState rasterizerState1 = new RasterizerState(); + rasterizerState1.CullMode = CullMode.None; + graphics.GraphicsDevice.RasterizerState = rasterizerState1; + foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) + { + pass.Apply(); + + graphics.GraphicsDevice.DrawPrimitives( + PrimitiveType.TriangleList, + 0, + 12 + ); + } + + + base.Draw(gameTime); + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Create_a_RenderTarget.md b/articles/monogame/howto/graphics/HowTo_Create_a_RenderTarget.md new file mode 100644 index 0000000..6394d64 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Create_a_RenderTarget.md @@ -0,0 +1,116 @@ +--- +title: How to create a Render Target +description: Demonstrates how to create a render target using a RenderTarget2D. +requireMSLicense: true +--- + +The example is very basic but the principles are the same, when drawing to a Render Texture we apply the following process. + +1. Set the Graphics Device to output to a texture. +2. Clear the buffer (or not depending on the use case). +3. Draw the full screen contents required in the Render Texture, e.g. a map or camera view. +4. Reset the Graphics device to the back buffer (screen). +5. Draw your game as normal. +6. Draw the Render Texture to the screen in the position we desire (e.g. in the lower corner for a mini-map), most likely on top of your game graphics. + +> [!TIP] +> The technique is very useful, especially if you are doing split-screen gaming and need to draw multiple camera views. + +## Requirements + +This sample uses a `grid` texture (available below) to draw to the [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) before then rendering the contents of the `Render Target` to the screen as a texture. + +![Grid Texture](../images/grid.png) + +Download the `Grid` texture and add it to your `Content Project` for this example. (see [How to Add Content](../content_pipeline/HowTo_GameContent_Add.md) for more information on this.) + +## Creating a Render Target + +1. Declare variables for a render target using the [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) class, for this example we will also be using a [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) for the "grid" texture we will output to the `Render Target`. + + ```csharp + private GraphicsDeviceManager graphics; + private SpriteBatch spriteBatch; + private Texture2D grid; + private RenderTarget2D renderTarget; + ``` + +2. Load the "grid" texture, which contains vertical and horizontal lines. + + ```csharp + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + // using "grid" which matches the NAME of the grid texture in the content project. + grid = Content.Load("grid"); + } + ``` + +3. Create the render target, giving it the same size as either the Texture (shown below) or the display back buffer (if you are rendering full screen), ideally in the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) method or later. + + ```csharp + renderTarget = new RenderTarget2D( + GraphicsDevice, + grid.Width, + grid.Height); + ``` + +4. Render the "grid" texture to the render target. + + Rendering to a [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) changes the Graphics Device output to write to a `texture` instead of the screen. Once you have finished rendering to the [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) you **MUST** reset the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) Render Target to `null` to return to drawing to the screen / back buffer. + + The example function below, sets the render target on the device, draws the texture (to the render target) using a [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch). When rendering is complete, it then resets the device render target to `null` (which resets the device to the back buffer). + + ```csharp + private void DrawRenderTarget() + { + // Set the device to the render target + graphics.GraphicsDevice.SetRenderTarget(renderTarget); + + // Clear the graphics buffer to a solid color + graphics.GraphicsDevice.Clear(Color.Black); + + // Draw the "grid" texture to the graphics buffer, currently outputting to the Render Texture. + spriteBatch.Begin(); + Vector2 pos = Vector2.Zero; + spriteBatch.Draw(grid, pos, Color.White); + spriteBatch.End(); + + // Reset the device to the back buffer + graphics.GraphicsDevice.SetRenderTarget(null); + } + ``` + +5. Draw the render target texture to the back buffer. + + With the render target populated using the `DrawRenderTarget` function, we can then draw the output to the screen. + + ```csharp + protected override void Draw(GameTime gameTime) + { + // Populate the RenderTarget + DrawRenderTarget(); + + // Clear the screen + GraphicsDevice.Clear(Color.CornflowerBlue); + + // Draw the contents of the Render Target texture + spriteBatch.Begin(); + spriteBatch.Draw(renderTarget, + new Vector2(200, 50), // x,y position + new Rectangle(0, 0, 32, 32), // just one grid + Color.White // no color scaling + ); + spriteBatch.End(); + + base.Draw(gameTime); + } + ``` + +The final output should look like the following: + +![Output](../images/HowTo_Create_a_RenderTarget_Final.png) + +Rendering a 32 by 32 square from the RenderTarget texture to a position 200 x 50 on the screen. diff --git a/articles/monogame/howto/graphics/HowTo_Create_a_StateObject.md b/articles/monogame/howto/graphics/HowTo_Create_a_StateObject.md new file mode 100644 index 0000000..66c2037 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Create_a_StateObject.md @@ -0,0 +1,60 @@ +--- +title: How to create a State Object +description: Demonstrates how to create a state object using any of the state object classes. +--- + +# How to create a State Object + +Demonstrates how to create a state object using any of the state object classes: [BlendState](xref:Microsoft.Xna.Framework.Graphics.BlendState), [DepthStencilState](xref:Microsoft.Xna.Framework.Graphics.DepthStencilState), [RasterizerState](xref:Microsoft.Xna.Framework.Graphics.RasterizerState), or [SamplerState](xref:Microsoft.Xna.Framework.Graphics.SamplerState). + +## Creating a State Object + +### To create a state object + +1. Declare three state object variables as fields in your game. + + This example declares three rasterizer state objects and uses them to change the culling state. + + ```csharp + RasterizerState rsCullNone; + ``` + +2. Create a customizable state object. + + Create a state object from the [RasterizerState](xref:Microsoft.Xna.Framework.Graphics.RasterizerState) class and initialize it by explicitly setting the cull mode. + + ```csharp + rsCullNone = new RasterizerState(); + rsCullNone.CullMode = CullMode.None; + rsCullNone.FillMode = FillMode.WireFrame; + rsCullNone.MultiSampleAntiAlias = false; + ``` + +3. Respond to the user pressing the A key on a gamepad to change the culling mode. + + The application starts with culling turned off; toggle between culling modes by pushing the A key on a gamepad. Unlike a customizable state object, use a built-in state object to create an object with a set of predefined state. + + ```csharp + if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed) + changeState = true; + + if ((changeState) && (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Released)) + { + if (GraphicsDevice.RasterizerState.CullMode == CullMode.None) + GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; + else if (GraphicsDevice.RasterizerState.CullMode == CullMode.CullCounterClockwiseFace) + GraphicsDevice.RasterizerState = RasterizerState.CullClockwise; + else if (GraphicsDevice.RasterizerState.CullMode == CullMode.CullClockwiseFace) + GraphicsDevice.RasterizerState = rsCullNone; + + changeState = false; + } + ``` + +> The example contains two triangles. The first one is rendered if you select clockwise winding order; the second triangle is rendered if you select counterclockwise winding order; both triangles are rendered if you select no culling. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Draw_3D_Primitives.md b/articles/monogame/howto/graphics/HowTo_Draw_3D_Primitives.md new file mode 100644 index 0000000..a6f9f2f --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Draw_3D_Primitives.md @@ -0,0 +1,245 @@ +--- +title: Drawing 3D Primitives using Lists or Strips +description: Demonstrates how to draw 3D primitives using lines and triangles arranged as strips or lists. +--- + +# Drawing 3D Primitives using Lists or Strips + +Demonstrates how to draw 3D primitives using lines and triangles arranged as strips or lists. + +A 3D primitive describes how vertex data is ordered. This example demonstrates line and triangle primitive types that are the basis for all drawing calls in the MonoGame Framework. To render primitives, you need to create a basic effect and transformation matrices. This topic follows the steps described in [Creating a Basic Effect](HowTo_Create_a_BasicEffect.md) to create an instance of [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect). This sample uses orthographic projection, but you can also use perspective projection to render primitives. The vertices used in the sample are of type [VertexPositionColor Structure](xref:Microsoft.Xna.Framework.Graphics.VertexPositionColor) which contains per-vertex position and color. + +## Creating Vertices + +The major steps for this example are: + +- Creating Vertices +- Drawing a Line List +- Drawing a Line Strip +- Drawing A Triangle List +- Drawing a Triangle Strip + +### To create vertices + +1. Create a list of vertices in 3D space that represent the points to draw. + + The following code creates eight vertices and stores them in an array of type **VertexPositionColor**. + + ``` csharp + primitiveList = new VertexPositionColor[points]; + + for (int x = 0; x < points / 2; x++) + { + for (int y = 0; y < 2; y++) + { + primitiveList[(x * 2) + y] = new VertexPositionColor( + new Vector3(x * 100, y * 100, 0), Color.White); + } + } + ``` + + These eight points form a triangle strip consisting of six triangles drawn along the plane z = 0, with the first point at (0, 0, 0). The camera is positioned at (0, 0, 1) looking at (0, 0, 0). An orthogonal projection matrix is created with the upper-left point at (0, 0) and the lower-right point at (800, 600). In addition, a translation matrix shifts the point set to the center of the screen. The code below positions the points, the camera and the required transformations. + + ``` csharp + viewMatrix = Matrix.CreateLookAt( + new Vector3(0.0f, 0.0f, 1.0f), + Vector3.Zero, + Vector3.Up + ); + + projectionMatrix = Matrix.CreateOrthographicOffCenter( + 0, + (float)GraphicsDevice.Viewport.Width, + (float)GraphicsDevice.Viewport.Height, + 0, + 1.0f, 1000.0f); + ``` + +## Drawing a Line List + +The example in this section uses the sample vertex list created by following step 1 in the Creating Vertices procedure. + +### To draw a line list + +1. Create an index array that indexes into the vertex buffer. + + This identifies a series of lines. + + ``` csharp + // Initialize an array of indices of type short. + lineListIndices = new short[(points * 2) - 2]; + + // Populate the array with references to indices in the vertex buffer + for (int i = 0; i < points - 1; i++) + { + lineListIndices[i * 2] = (short)(i); + lineListIndices[(i * 2) + 1] = (short)(i + 1); + } + ``` + +2. Render the lines by calling [DrawUserIndexedPrimitives](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice), which specifies [PrimitiveType.LineList](xref:Microsoft.Xna.Framework.Graphics.PrimitiveType) to determine how to interpret the data in the vertex array. + + ``` csharp + GraphicsDevice.DrawUserIndexedPrimitives( + PrimitiveType.LineList, + primitiveList, + 0, // vertex buffer offset to add to each element of the index buffer + 8, // number of vertices in pointList + lineListIndices, // the index buffer + 0, // first index element to read + 7 // number of primitives to draw + ); + ``` + +## Drawing a Line Strip + +The example in this section uses the same point list and renders the same output as the Drawing a Line List procedure. However, it uses a line strip primitive type when it identifies the indices of the vertex array to draw. Fewer indices are stored when you use a line strip. + +### To draw a line strip + +1. Create a list of indices to identify the order in which to draw the points in the specified point list. + + Only half the number of indices used for the line list are needed here because the data consist of a series of connected lines. + + ``` csharp + // Initialize an array of indices of type short. + lineStripIndices = new short[points]; + + // Populate the array with references to indices in the vertex buffer. + for (int i = 0; i < points; i++) + { + lineStripIndices[i] = (short)(i); + } + ``` + + This is equivalent to setting `lineStripIndices` to the following array, which consists of a series of *connected* lines between pointList\[0\], pointList\[1\], and pointList\[2\], and so forth. + + ``` csharp + lineStripIndices = new short[8]{ 0, 1, 2, 3, 4, 5, 6, 7 }; + ``` + +2. Render the line strip by calling [DrawUserIndexedPrimitives](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice), which specifies [PrimitiveType.LineStrip](xref:Microsoft.Xna.Framework.Graphics.PrimitiveType) to determine how to interpret the data in the vertex array. + + Fewer vertices are used to render the same number of primitives rendered earlier by the line list. + + > [!NOTE] + > In the example code, the line strip is rendered by a series of red lines instead of the white lines used for the previous line list. This is accomplished by changing the vertex color before you draw the line strip. After you complete the drawing, it reverts to the original color. In addition, vertex coloring was enabled for the basic effect (using [BasicEffect.VertexColorEnabled]](xref:Microsoft.Xna.Framework.Graphics.BasicEffect#Microsoft_Xna_Framework_Graphics_BasicEffect_VertexColorEnabled) Property). + > The color change indicates a different primitive type was used to achieve the same result. + + ``` csharp + for (int i = 0; i < primitiveList.Length; i++) + primitiveList[i].Color = Color.Red; + + GraphicsDevice.DrawUserIndexedPrimitives( + PrimitiveType.LineStrip, + primitiveList, + 0, // vertex buffer offset to add to each element of the index buffer + 8, // number of vertices to draw + lineStripIndices, + 0, // first index element to read + 7 // number of primitives to draw + ); + for (int i = 0; i < primitiveList.Length; i++) + primitiveList[i].Color = Color.White; + ``` + +## Drawing A Triangle List + +A triangle list, like a line list, is a primitive type that indicates you need to interpret the vertices in the vertex buffer as a series of separately drawn triangles. + +### To draw a triangle list + +1. Create an array to hold the list of indices that identify a series of triangles to draw from the specified point list. + + ``` csharp + triangleListIndices = new short[(width - 1) * (height - 1) * 6]; + + for (int x = 0; x < width - 1; x++) + { + for (int y = 0; y < height - 1; y++) + { + triangleListIndices[(x + y * (width - 1)) * 6] = (short)(2 * x); + triangleListIndices[(x + y * (width - 1)) * 6 + 1] = (short)(2 * x + 1); + triangleListIndices[(x + y * (width - 1)) * 6 + 2] = (short)(2 * x + 2); + + triangleListIndices[(x + y * (width - 1)) * 6 + 3] = (short)(2 * x + 2); + triangleListIndices[(x + y * (width - 1)) * 6 + 4] = (short)(2 * x + 1); + triangleListIndices[(x + y * (width - 1)) * 6 + 5] = (short)(2 * x + 3); + } + } + ``` + + This is equivalent to setting `triangleListIndices` to the following array, which consists of a series of triangles between pointList\[0\], pointList\[1\], and pointList\[2\], and so forth. + + ``` csharp + triangleListIndices = new short[18]{ 0, 1, 2, 2, 1, 3, 2, 3, 4, 4, 3, 5, 4, 5, 6, 6, 5, 7 }; + ``` + +2. Render the lines by calling [DrawUserIndexedPrimitives](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) + + This specifies [PrimitiveType.TriangleList](xref:Microsoft.Xna.Framework.Graphics.PrimitiveType), which determines how the data in the vertex array is interpreted. + + ``` csharp + GraphicsDevice.DrawUserIndexedPrimitives( + PrimitiveType.TriangleList, + primitiveList, + 0, // vertex buffer offset to add to each element of the index buffer + 8, // number of vertices to draw + triangleListIndices, + 0, // first index element to read + 6 // number of primitives to draw + ); + ``` + +## Drawing a Triangle Strip + +A triangle strip is a set of triangles that share multiple vertices. This example shows you how to render an object that looks the same as the object rendered with a triangle list. However, fewer vertices are needed because the triangles share multiple vertices. + +### To draw a triangle strip + +1. Create an array to hold the list of indices that identify a strip of triangles. + + ``` csharp + // Initialize an array of indices of type short. + triangleStripIndices = new short[points]; + + // Populate the array with references to indices in the vertex buffer. + for (int i = 0; i < points; i++) + { + triangleStripIndices[i] = (short)i; + } + ``` + + This is equivalent to setting `triangleStripIndices` to the following array, which consists of a series of *connected* triangles between pointList\[0\], pointList\[1\], and pointList\[2\], and so forth. + + ``` csharp + triangleStripIndices = new short[8]{ 0, 1, 2, 3, 4, 5, 6, 7 }; + ``` + +2. Render the lines by calling [DrawUserIndexedPrimitives](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice). + + This specifies [PrimitiveType.TriangleStrip](xref:Microsoft.Xna.Framework.Graphics.PrimitiveType) to determine how to interpret the data in the vertex array. Fewer vertices are used to render the same number of primitives rendered earlier by the triangle list. + + > [!NOTE] + > In the example code, the triangle strip is rendered by a series of red lines instead of the white lines used for the previous triangle list. The color change indicates a different primitive type was used to achieve the same result. + + ``` csharp + for (int i = 0; i < primitiveList.Length; i++) + primitiveList[i].Color = Color.Red; + + GraphicsDevice.DrawUserIndexedPrimitives( + PrimitiveType.TriangleStrip, + primitiveList, + 0, // vertex buffer offset to add to each element of the index buffer + 8, // number of vertices to draw + triangleStripIndices, + 0, // first index element to read + 6 // number of primitives to draw + ); + for (int i = 0; i < primitiveList.Length; i++) + primitiveList[i].Color = Color.White; + ``` + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Draw_A_Sprite.md b/articles/monogame/howto/graphics/HowTo_Draw_A_Sprite.md new file mode 100644 index 0000000..fa44150 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Draw_A_Sprite.md @@ -0,0 +1,65 @@ +--- +title: Drawing a Sprite +description: Demonstrates how to draw a sprite by using the SpriteBatch class +--- + +# Drawing a Sprite + +Demonstrates how to draw a sprite by using the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) class. + +## To draw a sprite on screen + +1. Derive a class from [Game](xref:Microsoft.Xna.Framework.Game). +2. Define a [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object as a field on your game class. +3. In your [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) method, construct the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object, passing the current graphics device. +4. Load the textures that will be used for drawing sprites in [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent). + In this case, the example uses the **Content** member to load a texture from the MonoGame Framework Content Pipeline. The texture must be in the project, with the same name passed to [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager#Microsoft_Xna_Framework_Content_ContentManager_Load__1_System_String_). + + ```csharp + private Texture2D SpriteTexture; + private Rectangle TitleSafe; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + SpriteTexture = Content.Load("ship"); + TitleSafe = GetTitleSafeArea(.8f); + } + ``` + +5. In the overridden [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, call [GraphicsDevice.Clear](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice#Microsoft_Xna_Framework_Graphics_GraphicsDevice_Clear_Microsoft_Xna_Framework_Color_). +6. After [GraphicsDevice.Clear](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice#Microsoft_Xna_Framework_Graphics_GraphicsDevice_Clear_Microsoft_Xna_Framework_Color_), call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. +7. Create a [Vector2](xref:Microsoft.Xna.Framework.Vector2) to represent the screen position of the sprite. +8. Call [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object, passing the texture to draw, the screen position, and the color to apply. +9. Use [Color.White](xref:Microsoft.Xna.Framework.Color) to draw the texture without any color effects. +10. When all the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + + ```csharp + protected override void Draw(GameTime gameTime) + { + graphics.GraphicsDevice.Clear(Color.CornflowerBlue); + spriteBatch.Begin(); + Vector2 pos = new Vector2(TitleSafe.Left, TitleSafe.Top); + spriteBatch.Draw(SpriteTexture, pos, Color.White); + spriteBatch.End(); + base.Draw(gameTime); + } + ``` + +## See Also + +### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Draw_Sprite_Background.md b/articles/monogame/howto/graphics/HowTo_Draw_Sprite_Background.md new file mode 100644 index 0000000..172ece6 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Draw_Sprite_Background.md @@ -0,0 +1,93 @@ +--- +title: Drawing a Masked Sprite over a Background +description: Demonstrates how to draw a foreground and background sprite using the SpriteBatch class, where only part of the foreground sprite masks the background. +--- + +# Drawing a Masked Sprite over a Background + +Demonstrates how to draw a foreground and background sprite using the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) class, where only part of the foreground sprite masks the background. + +The foreground sprite in this example must include masking information. + +## Drawing a Foreground and Background Sprite + +1. Open the `Game1` class, and load your content as described in the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). + + ```csharp + private Vector2 ViperPos; // Position of foreground sprite on screen + private Viewport viewport; + SpriteBatch spriteBatch; + Texture2D ShipTexture; + Texture2D StarTexture; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + StarTexture = Content.Load("starfield"); + ShipTexture = Content.Load("ship"); + viewport = graphics.GraphicsDevice.Viewport; + + ViperPos.X = viewport.Width / 2; + ViperPos.Y = viewport.Height - 100; + } + ``` + +2. In [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method of your game class, call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) for the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch). + +3. Specify [BlendState.None](xref:Microsoft.Xna.Framework.Graphics.BlendState). + This will tell the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) to ignore alpha color values when drawing sprites. By default, the z-order of sprites is the order in which they are drawn. + +4. Call the [Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) method, passing in the `StarTexture`. Then call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End). + + ```csharp + public override void Draw (GameTime game) + { + spriteBatch.Begin(BlendState.None); + spriteBatch.Draw (StarTexture); + spriteBatch.End(); + } + ``` + +5. Underneath the code we wrote previously, call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) for the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) again. + +6. This time, specify [BlendState.AlphaBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState). + + This will cause pixels on the sprite with an alpha value less than 255 to become progressively transparent based on the magnitude of the alpha value. An alpha of 0 will make the pixel completely transparent. Calling [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) with no parameters causes [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) to default to [BlendState.AlphaBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState). + +7. Call the [Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) method, passing the `ShipTexture`, `ViperPos` and finally [Color.White](xref:Microsoft.Xna.Framework.Color) . Then call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End). + + ```csharp + public override void Draw (GameTime game) + { + spriteBatch.Begin(BlendState.None); + spriteBatch.Draw (StarTexture); + spriteBatch.End(); + + spriteBatch.Begin(BlendState.AlphaBlend); + spriteBatch.Draw (ShipTexture, ViperPos, Color.White); + spriteBatch.End(); + } + ``` + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Draw_Sprite_Over_Model.md b/articles/monogame/howto/graphics/HowTo_Draw_Sprite_Over_Model.md new file mode 100644 index 0000000..44b535f --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Draw_Sprite_Over_Model.md @@ -0,0 +1,126 @@ +--- +title: Drawing a Sprite Over a Model +description: Demonstrates how to draw a sprite so that it obscures a model. In this example, we are drawing an animated sprite representing an explosion over the current screen position of a 3D model. +--- + +# Drawing a Sprite Over a Model + +Demonstrates how to draw a sprite so that it obscures a model. In this example, we are drawing an animated sprite representing an explosion over the current screen position of a 3D model. + +For this sample, the camera is a standard arc ball camera, implemented by camera.cs. The 3D model file is a simple ring, implemented by ring16b.x. The animated explosion sprite is implemented by explosion.dds. These files can be found in the complete sample. See [Animating a Sprite](HowTo_Animate_Sprite.md) for an example of the **AnimatedTexture** class. + +## Drawing a Sprite Over a 3D Model + +1. In your [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method, handle the input to move your camera, then call **UpdateFrame** on the **AnimatedTexture**. + + ```csharp + GamePadState PlayerOne = GamePad.GetState(PlayerIndex.One); + + // Move the camera using thumbsticks + MoveCamera(PlayerOne); + + // Start or stop the animated sprite using buttons + if (PlayerOne.Buttons.A == ButtonState.Pressed) + explosion.Play(); + if (PlayerOne.Buttons.B == ButtonState.Pressed) + explosion.Stop(); + + // Update the animated sprite + explosion.UpdateFrame((float)gameTime.ElapsedGameTime.TotalSeconds); + ``` + +2. Use [BoundingSphere.CreateMerged](xref:Microsoft.Xna.Framework.BoundingSphere#Microsoft_Xna_Framework_BoundingSphere_CreateMerged_Microsoft_Xna_Framework_BoundingSphere_Microsoft_Xna_Framework_BoundingSphere_) to create a [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) that contains all the **BoundingSphere** values for each [ModelMesh](xref:Microsoft.Xna.Framework.Graphics.ModelMesh) in the [Model](xref:Microsoft.Xna.Framework.Graphics.Model). + +3. Use [Viewport.Project](xref:Microsoft.Xna.Framework.Graphics.Viewport#Microsoft_Xna_Framework_Graphics_Viewport_Project_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_) to find the center point of that sphere, which is the center of the model in screen coordinates. + + ```csharp + // Create a total bounding sphere for the mesh + BoundingSphere totalbounds = new BoundingSphere(); + foreach (ModelMesh mesh in Ring.Meshes) + { + totalbounds = BoundingSphere.CreateMerged(totalbounds, + mesh.BoundingSphere); + } + + // Project the center of the 3D object to the screen, and center the + // sprite there + Vector3 center = GraphicsDevice.Viewport.Project(totalbounds.Center, + projectionMatrix, Camera1.ViewMatrix, Matrix.Identity); + explosionpos.X = center.X; + explosionpos.Y = center.Y; + ``` + +4. Take the **BoundingSphere** for the model and use it to create a [BoundingBox](xref:Microsoft.Xna.Framework.BoundingBox) with [BoundingBox.CreateFromSphere](xref:Microsoft.Xna.Framework.BoundingBox#Microsoft_Xna_Framework_BoundingBox_CreateFromSphere_Microsoft_Xna_Framework_BoundingSphere_). + +5. Use [Viewport.Project](xref:Microsoft.Xna.Framework.Graphics.Viewport#Microsoft_Xna_Framework_Graphics_Viewport_Project_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_) to find the corner of the box farthest from the center and use the return value to scale the sprite appropriately. + + ```csharp + // Create a bounding box from the bounding sphere, + // and find the corner that is farthest away from + // the center using Project + BoundingBox extents = BoundingBox.CreateFromSphere(totalbounds); + float maxdistance = 0; + float distance; + Vector3 screencorner; + foreach (Vector3 corner in extents.GetCorners()) + { + screencorner = GraphicsDevice.Viewport.Project(corner, + projectionMatrix, Camera1.ViewMatrix, Matrix.Identity); + distance = Vector3.Distance(screencorner, center); + if (distance > maxdistance) + maxdistance = distance; + } + + // Scale the sprite using the two points (the sprite is + // 75 pixels square) + explosion.Scale = maxdistance / 75; + ``` + +6. In your [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, draw the [Model](xref:Microsoft.Xna.Framework.Graphics.Model) normally, and then draw the animated sprite using the position calculated in [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_). + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + //Draw the model, a model can have multiple meshes, so loop + foreach (ModelMesh mesh in Ring.Meshes) + { + //This is where the mesh orientation is set, as well as + //our camera and projection + foreach (BasicEffect effect in mesh.Effects) + { + effect.EnableDefaultLighting(); + effect.World = Matrix.Identity * + Matrix.CreateRotationY(RingRotation) * + Matrix.CreateTranslation(RingPosition); + effect.View = Camera1.ViewMatrix; + effect.Projection = projectionMatrix; + } + //Draw the mesh, will use the effects set above. + mesh.Draw(); + } + + // Draw the sprite over the 3D object + // spriteBatch.Begin(SpriteBlendMode.AlphaBlend, + // SpriteSortMode.Deferred, SaveStateMode.SaveState); + spriteBatch.Begin(); + explosion.DrawFrame(spriteBatch, explosionpos); + spriteBatch.End(); + + base.Draw(gameTime); + } + ``` + +## See Also + +### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) +[What Is Color Blending?](../../whatis/graphics/WhatIs_ColorBlending.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Draw_Text.md b/articles/monogame/howto/graphics/HowTo_Draw_Text.md new file mode 100644 index 0000000..e5be9b5 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Draw_Text.md @@ -0,0 +1,116 @@ +--- +title: Drawing Text with a Sprite +description: Demonstrates how to import a SpriteFont into a project and to draw text using DrawString +--- + +# Drawing Text with a Sprite + +Demonstrates how to import a [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) into a project and to draw text using [SpriteBatch.DrawString](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_DrawString_Microsoft_Xna_Framework_Graphics_SpriteFont_System_String_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_). + +## Adding a Sprite Font and Drawing Text + +1. Double click on your Content.mgcb file in Solution Explorer, click **New Item** Button. + +2. In the **Add New Item** dialog box, select **Sprite Font Description** and add the filename in the edit box at the top of the dialog. + + You may find it convenient at this point to change the name of the new file from "SpriteFont1" to the friendly name of the font you intend to load (keeping the .spritefont file extension). The friendly name identifies the font once it is installed on your computer, for example, "Courier New" or "Times New Roman." When you reference the font in your code, you must use the friendly name you have assigned it. + Pipeline tool creates a new .spritefont file for your font. + +3. Right click on your new font file in the Pipeline project explorer and select Open (or Open With to choose your preferred editor). + +4. If you did not name the new file with the font's friendly name, type the friendly name of the font to load into the FontName element. + Again, this is not the name of a font file, but rather the name that identifies the font once it is installed on your computer. You can use the Fonts folder in the **Control Panel** to see the names of fonts installed on your system, and to install new ones. The content pipeline supports the same fonts as the [System.Drawing.Font](http://msdn.microsoft.com/en-us/library/system.drawing.font.aspx) class, including TrueType fonts, but not bitmap (.fon) fonts. You may find it convenient to save the new .spritefont file using this friendly name. When you reference the font in your code, you must use the friendly name you have assigned it. + + If you want to use a custom font, you are put the .ttf or .oft in the same directory as the .spritefont file and the build system will pick it up. There is no need to install the font system wide. + +5. If necessary, change the **Size** entry to the point size you desire for your font. + +6. If necessary, change the **Style** entry to the style of font to import. + You can specify **Regular**, **Bold**, **Italic**, or **Bold, Italic**. The **Style** entry is case sensitive. + +7. Specify the character regions to import for this font. + + Character regions specify which characters in the font are rendered by the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont). You can specify the start and end of the region by using the characters themselves, or by using their decimal values with an &# prefix. The default character region includes all the characters between the space and tilde characters, inclusive. + +### To draw text on the screen + +1. Add a Sprite Font to your project as described above. + +2. Create a [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) object to encapsulate the imported font. + +3. Create a [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object for drawing the font on the screen. + +4. In your [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) method, call [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager#Microsoft_Xna_Framework_Content_ContentManager_Load__1_System_String_), specifying the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) class and the asset name of the imported font. + +5. Create your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object, passing the current [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice). + + ```csharp + SpriteFont Font1; + Vector2 FontPos; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + Font1 = Content.Load("Courier New"); + + // TODO: Load your game content here + FontPos = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, + graphics.GraphicsDevice.Viewport.Height / 2); + } + ``` + +6. In your [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) on the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + +7. If necessary, determine the origin of your text. + + If you want to draw your text centered on a point, you can find the center of the text by calling [SpriteFont.MeasureString](xref:Microsoft.Xna.Framework.Graphics.SpriteFont#Microsoft_Xna_Framework_Graphics_SpriteFont_MeasureString_System_String_) and dividing the returned vector by 2. + +8. Call [SpriteBatch.DrawString](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_DrawString_Microsoft_Xna_Framework_Graphics_SpriteFont_System_String_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) to draw your output text, specifying the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) object for the font you want to use. + + All other parameters of [SpriteBatch.DrawString](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_DrawString_Microsoft_Xna_Framework_Graphics_SpriteFont_System_String_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) produce the same effects as a call to [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_). + +9. Call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) after all text is drawn. + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + spriteBatch.Begin(); + + // Draw Hello World + string output = "Hello World"; + + // Find the center of the string + Vector2 FontOrigin = Font1.MeasureString(output) / 2; + // Draw the string + spriteBatch.DrawString(Font1, output, FontPos, Color.LightGreen, + 0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f); + + spriteBatch.End(); + base.Draw(gameTime); + } + ``` + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.DrawString](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_DrawString_Microsoft_Xna_Framework_Graphics_SpriteFont_System_String_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) +[ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager#Microsoft_Xna_Framework_Content_ContentManager_Load__1_System_String_) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Draw_Textured_Quad.md b/articles/monogame/howto/graphics/HowTo_Draw_Textured_Quad.md new file mode 100644 index 0000000..9c0d274 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Draw_Textured_Quad.md @@ -0,0 +1,87 @@ +--- +title: Creating a Custom Effect with Texturing +description: Demonstrates how to use a custom effect and a texture to render a 3D object. +--- + +# Creating a Custom Effect with Texturing + +Demonstrates how to use a custom effect and a texture to render a 3D object. + +## Using a custom effect and a texture + +### To use a custom effect and a texture + +1. Create a vertex declaration that contains a position and a texture coordinate. + +2. Create a vertex buffer from the vertex declaration. + + ``` csharp + vertexDeclaration = new VertexDeclaration(new VertexElement[] + { + new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), + new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0) + } + ); + + vertexBuffer = new VertexBuffer( + graphics.GraphicsDevice, + vertexDeclaration, + number_of_vertices, + BufferUsage.None + ); + ``` + +3. Create a custom effect using the [Effect](xref:Microsoft.Xna.Framework.Graphics.Effect) class. + +4. Load the [Effect](xref:Microsoft.Xna.Framework.Graphics.Effect) object using the [ContentManager.Load\](xref:Microsoft.Xna.Framework.Content.ContentManager) method to load the .fx file. + +5. Load a [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) object using the [ContentManager.Load\](xref:Microsoft.Xna.Framework.Content.ContentManager)) method to load the asset. + +6. Call [SetValue](xref:Microsoft.Xna.Framework.Graphics.Effect) to initialize each effect parameter using the corresponding game property. + +7. Initialize the [CurrentTechnique](xref:Microsoft.Xna.Framework.Graphics.Effect) to a technique that exists in the .fx file. + + ``` csharp + effect = Content.Load("ReallySimpleTexture"); + + Texture2D texture = Content.Load("XNA_pow2"); + + effect.Parameters["WorldViewProj"].SetValue(worldViewProjection); + effect.Parameters["UserTexture"].SetValue(texture); + + effect.CurrentTechnique = effect.Techniques["TransformAndTexture"]; + ``` + +8. Render the effect. + +9. Set the [RasterizerState](xref:Microsoft.Xna.Framework.Graphics.RasterizerState) property to turn culling off so that all primitives will be drawn regardless of the order of the vertices. + +10. Loop through each pass in the effect calling [DrawPrimitives](https://msdn.microsoft.com/en-us/library/m:microsoft.xna.framework.graphics.graphicsdevice.drawprimitives\(microsoft.xna.framework.graphics.primitivetype%2csystem.int32%2csystem.int32\)). + + ``` csharp + graphics.GraphicsDevice.Clear(Color.SteelBlue); + + RasterizerState rasterizerState = new RasterizerState(); + rasterizerState.CullMode = CullMode.None; + graphics.GraphicsDevice.RasterizerState = rasterizerState; + foreach (EffectPass pass in effect.CurrentTechnique.Passes) + { + pass.Apply(); + + graphics.GraphicsDevice.DrawPrimitives( + PrimitiveType.TriangleList, + 0, // start vertex + 12 // number of primitives to draw + ); + } + ``` + +## See Also + +### Concepts + +[3D Pipeline Basics](../../whatis/graphics/WhatIs_3DRendering.md) + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_DynamicallyUpdateVertices.md b/articles/monogame/howto/graphics/HowTo_DynamicallyUpdateVertices.md new file mode 100644 index 0000000..b79468e --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_DynamicallyUpdateVertices.md @@ -0,0 +1,32 @@ +--- +title: How to Dynamically Update Vertex Data +description: Describes techniques for dynamically updating vertex data in an MonoGame game. +--- + +# Dynamically Updating Vertex Data + +Geometry in a 3D game is defined by vertex data. Sometimes, a game needs to modify vertex data or even generate new vertex data dynamically (at run time). Here are some solutions for dynamically updating vertex data. + +## Updating a Set of Primitives Dynamically + +The [Primitives Sample](https://github.com/simondarksidej/XNAGameStudio/wiki/Primitives) demonstrates a dynamic vertex buffer that is generated during each rendering frame. The sample renders primitives by first calling `Begin`, adding the necessary vertices, using the `Add` method, and then calling `End`. This forces the buffer to be drawn to the current device. The `Flush` method calls [GraphicsDevice.DrawUserPrimitives](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawUserPrimitives__1_Microsoft_Xna_Framework_Graphics_PrimitiveType___0___System_Int32_System_Int32_) method when `End` is called or when the buffer has no room for new vertices. If there is no room, the buffer is written to the device, it is reset, and the pending vertices are added. + +## Dynamically Rendering a Persistent Set of Primitives + +The [Particle 3D Sample](https://github.com/simondarksidej/XNAGameStudio/wiki/Particles-3D), implements a dynamic vertex buffer that contains custom vertices with a limited lifespan. The application adds and removes particles into a fixed length buffer. The custom shader of the sample renders the active subset of vertices dynamically. Because particles have a limited lifespan, the `ParticleSystem` class handles all adding, updating, and deleting of the vertex buffer in real time. + +## Generating Geometry Programmatically + +Sometimes, your game needs to generate geometry because the geometry is not known at design-time or it changes at run time. For this scenario, create a dynamic vertex and index buffer, and use [VertexBuffer.SetData](xref:Microsoft.Xna.Framework.Graphics.VertexBuffer) and [IndexBuffer.SetData](xref:Microsoft.Xna.Framework.Graphics.IndexBuffer) to set or change the data at run time. + +## Remarks + +Create a dynamic vertex or index buffer using [DynamicVertexBuffer](xref:Microsoft.Xna.Framework.Graphics.DynamicVertexBuffer) and [DynamicIndexBuffer](xref:Microsoft.Xna.Framework.Graphics.DynamicIndexBuffer) ; create a static vertex or index buffer using [VertexBuffer](xref:Microsoft.Xna.Framework.Graphics.VertexBuffer) and [IndexBuffer](xref:Microsoft.Xna.Framework.Graphics.IndexBuffer). Use a dynamic buffer for vertex data that is updated every render frame, otherwise, use a static buffer. + +The samples are located on the App Hub Web site. For a more advanced solution for dynamic vertex updating, download the [Generated Geometry Sample](http://go.microsoft.com/fwlink/?LinkId=93007). This sample uses the [MeshBuilder](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshBuilder) helper class and a custom processor to generate a terrain map from a bitmap loaded by the content manager. Specifically, examine the `Process` method, located in TerrainProcessor.cs, which programmatically creates the terrain geometry based on input from the specified bitmap. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Enable_Anti_Aliasing.md b/articles/monogame/howto/graphics/HowTo_Enable_Anti_Aliasing.md new file mode 100644 index 0000000..1749c73 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Enable_Anti_Aliasing.md @@ -0,0 +1,77 @@ +--- +title: How to enable anti-aliasing +description: Demonstrates how to enable anti-aliasing for your game. +--- + +# Enabling Anti-aliasing (Multisampling) + +Demonstrates how to enable anti-aliasing for your game. + +**Figure 1.  Anti-aliasing the edges of a cube: multi-sampling is disabled on the left, and enabled on the right.** + +![Anti-aliasing the edges of a cube: multi-sampling is disabled on the left, and enabled on the right](../images/graphics_aa.jpg) + +Anti-aliasing is a technique for minimizing distortion artifacts caused by aliasing when rendering a high-resolution signal (such as a sharp edge) at a low resolution (such as in a render target with a fixed number of pixel locations). anti-aliasing smooths sharp edges by partially rendering to neighboring pixels. This technique is also called multi-sampling because each pixel value can be the result of multiple samples. + +## Enabling Anti-aliasing + +### To enable anti-aliasing in your game + +* Render 3D geometry. One way to do this is by creating a BasicEffect using the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class. For more detail, see [Creating a Basic Effect](HowTo_Create_a_BasicEffect.md). + +* Set [PreferMultiSampling](/api/Microsoft.Xna.Framework.GraphicsDeviceManager.html#Microsoft_Xna_Framework_GraphicsDeviceManager_PreferMultiSampling) to **true** in your [Game](xref:Microsoft.Xna.Framework.Game) class constructor. + + ```csharp + graphics.PreferMultiSampling = true; + ``` + +* Set the view matrix to place the camera close to the object so you can more clearly see the smoothed, anti-aliased edges. + + ```csharp + worldMatrix = Matrix.CreateRotationX(tilt) * Matrix.CreateRotationY(tilt); + + viewMatrix = Matrix.CreateLookAt(new Vector3(1.75f, 1.75f, 1.75f), Vector3.Zero, Vector3.Up); + + projectionMatrix = Matrix.CreatePerspectiveFieldOfView( + MathHelper.ToRadians(45), // 45 degree angle + (float)GraphicsDevice.Viewport.Width / + (float)GraphicsDevice.Viewport.Height, + 1.0f, 100.0f); + ``` + +* Draw the geometry by calling [GraphicsDevice.DrawPrimitives](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawPrimitives_Microsoft_Xna_Framework_Graphics_PrimitiveType_System_Int32_System_Int32_). + + ```csharp + RasterizerState rasterizerState1 = new RasterizerState(); + rasterizerState1.CullMode = CullMode.None; + graphics.GraphicsDevice.RasterizerState = rasterizerState1; + foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) + { + pass.Apply(); + + graphics.GraphicsDevice.DrawPrimitives( + PrimitiveType.TriangleList, + 0, + 12 + ); + } + ``` + +## See Also + +### Concepts + +[3D Pipeline Basics](../../whatis/graphics/WhatIs_3DRendering.md) +[What Is anti-aliasing?](../../whatis/graphics/WhatIs_antialiasing.md) + +#### Reference + +[GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) +[PreparingDeviceSettings](/api/Microsoft.Xna.Framework.GraphicsDeviceManager.html#Microsoft_Xna_Framework_GraphicsDeviceManager_PreparingDeviceSettings) +[PresentationParameters](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_FitCameraToScene.md b/articles/monogame/howto/graphics/HowTo_FitCameraToScene.md new file mode 100644 index 0000000..36b2415 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_FitCameraToScene.md @@ -0,0 +1,80 @@ +--- +title: How to position the Camera +description: Demonstrates how to position the camera so that all objects in a scene are within the view frustum while maintaining the camera's original orientation. +--- + +# Positioning the Camera + +Demonstrates how to position the camera so that all objects in a scene are within the view frustum while maintaining the camera's original orientation. + +## Positioning the Camera to View All Objects in a Scene + +### To position the camera to view all objects in a scene + +1. Create a [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) class that contains all of the objects in the scene. To create the sphere, loop through all of the objects in the scene, merging the [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) classes that contain them with **CreateMerged**. + +2. If you are not already tracking the [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) classes for collision detection, use **CreateFromBoundingBox** or **CreateFromPoints** to create them from [BoundingBox](xref:Microsoft.Xna.Framework.BoundingBox) classes or points. + + In this example, the [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) classes are created from [BoundingBox](xref:Microsoft.Xna.Framework.BoundingBox) classes. + + ```csharp + BoundingSphere GetSceneSphere() + { + BoundingSphere sceneSphere = + new BoundingSphere(new Vector3(.5f, 1, .5f), 1.5f); + for (int z = 0; z < 5; z++) + { + for (int x = 0; x < 5; x++) + { + BoundingSphere boundingSphere = + sphere.Meshes[0].BoundingSphere; + boundingSphere.Center = new Vector3(x * 3, 0, z * 3); + + sceneSphere = BoundingSphere.CreateMerged( + sceneSphere, boundingSphere); + } + } + + return sceneSphere; + } + ``` + +3. Set the position of the camera to the center of the [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) that contains the scene. + + ```csharp + cameraPosition = sceneSphere.Center; + ``` + +4. Determine the distance from the center of the [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) that the camera needs to be to view the entire scene. + + This distance is equal to the hypotenuse of the triangle formed by the center of the sphere, the desired camera position, and the point where the sphere touches the view frustum. One angle of the triangle is known to be the field of view of the camera divided by two. One leg of the triangle is known to be the radius of the sphere. Given these two measurements, you can calculate the hypotenuse as the radius of the sphere divided by the sine of half the field of view. + + ```csharp + float distanceToCenter = + sceneSphere.Radius / (float)Math.Sin(FOV / 2); + ``` + +5. Get the [Backward](xref:Microsoft.Xna.Framework.Matrix.Backward) vector of the view [Matrix](xref:Microsoft.Xna.Framework.Matrix) and flip its X component. + + ```csharp + Vector3 back = view.Backward; + back.X = -back.X; //flip x's sign + ``` + +6. To move the camera backward with respect to its orientation, multiply the desired distance by the adjusted back vector from the previous step. + + The camera is now facing the center of the sphere containing the scene and is far enough back that the sphere fits in the camera's view frustum. + + ```csharp + cameraPosition += (back * distanceToCenter); + ``` + +## See Also + +[Rotating and Moving the Camera](HowTo_RotateMoveCamera.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_FullScreen.md b/articles/monogame/howto/graphics/HowTo_FullScreen.md new file mode 100644 index 0000000..42de1cb --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_FullScreen.md @@ -0,0 +1,31 @@ +--- +title: How to create a Full-Screen Game +description: Demonstrates how to start a game in full-screen mode. +--- + +# Creating a Full-Screen Game + +Demonstrates how to start a game in full-screen mode. + +## Creating a Full-Screen Game + +### To create a full-screen game + +1. Derive a class from [Game](xref:Microsoft.Xna.Framework.Game). + +2. After creating the [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager), set its [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth) and [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight) to the desired screen height and width. + +3. Set [IsFullScreen](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.IsFullScreen) to **true**. + + ```csharp + this.graphics.PreferredBackBufferWidth = 480; + this.graphics.PreferredBackBufferHeight = 800; + + this.graphics.IsFullScreen = true; + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Make_Scrolling_Background.md b/articles/monogame/howto/graphics/HowTo_Make_Scrolling_Background.md new file mode 100644 index 0000000..31ba0b7 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Make_Scrolling_Background.md @@ -0,0 +1,139 @@ +--- +title: Making a Scrolling Background +description: Demonstrates how to draw a scrolling background sprite using the SpriteBatch class +--- + +# Making a Scrolling Background + +Demonstrates how to draw a scrolling background sprite using the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) class. + +## Drawing a Scrolling Background Sprite + +1. Create the game class. + +2. Load resources as described in the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). + +3. Load the background texture. + + ```csharp + private ScrollingBackground myBackground; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + myBackground = new ScrollingBackground(); + Texture2D background = Content.Load("starfield"); + myBackground.Load(GraphicsDevice, background); + } + ``` + +4. Determine the size of the background texture and the size of the screen. + + The texture size is determined using the [Height](xref:Microsoft.Xna.Framework.Graphics.Texture2D.Height) and [Width](xref:Microsoft.Xna.Framework.Graphics.Texture2D.Width) properties, and the screen size is determined using the [Viewport](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Viewport) property on the graphics device. + +5. Using the texture and screen information, set the origin of the texture to the center of the top edge of the texture, and the initial screen position to the center of the screen. + + ```csharp + // class ScrollingBackground + private Vector2 screenpos, origin, texturesize; + private Texture2D mytexture; + private int screenheight; + public void Load( GraphicsDevice device, Texture2D backgroundTexture ) + { + mytexture = backgroundTexture; + screenheight = device.Viewport.Height; + int screenwidth = device.Viewport.Width; + // Set the origin so that we're drawing from the + // center of the top edge. + origin = new Vector2( mytexture.Width / 2, 0 ); + // Set the screen position to the center of the screen. + screenpos = new Vector2( screenwidth / 2, screenheight / 2 ); + // Offset to draw the second texture, when necessary. + texturesize = new Vector2( 0, mytexture.Height ); + } + ``` + +6. To scroll the background, change the screen position of the background texture in your [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method. + + This example moves the background down 100 pixels per second by increasing the screen position's Y value. + + ```csharp + protected override void Update(GameTime gameTime) + { + ... + // The time since Update was called last. + float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; + + // TODO: Add your game logic here. + myBackground.Update(elapsed * 100); + + base.Update(gameTime); + } + ``` + + The Y value is kept no larger than the texture height, making the background scroll from the bottom of the screen back to the top. + + ```csharp + public void Update( float deltaY ) + { + screenpos.Y += deltaY; + screenpos.Y = screenpos.Y % mytexture.Height; + } + // ScrollingBackground.Draw + ``` + +7. Draw the background using the origin and screen position calculated in [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) and [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_). + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + spriteBatch.Begin(); + myBackground.Draw(spriteBatch); + spriteBatch.End(); + + base.Draw(gameTime); + } + ``` + + In case the texture doesn't cover the screen, another texture is drawn. This subtracts the texture height from the screen position using the **texturesize** vector created at load time. This creates the illusion of a loop. + + ```csharp + public void Draw( SpriteBatch batch ) + { + // Draw the texture, if it is still onscreen. + if (screenpos.Y < screenheight) + { + batch.Draw( mytexture, screenpos, null, + Color.White, 0, origin, 1, SpriteEffects.None, 0f ); + } + // Draw the texture a second time, behind the first, + // to create the scrolling illusion. + batch.Draw( mytexture, screenpos - texturesize, null, + Color.White, 0, origin, 1, SpriteEffects.None, 0f ); + } + ``` + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) +[Drawing a Masked Sprite over a Background](HowTo_Draw_Sprite_Background.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_RenderModel.md b/articles/monogame/howto/graphics/HowTo_RenderModel.md new file mode 100644 index 0000000..086bf4d --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_RenderModel.md @@ -0,0 +1,153 @@ +--- +title: How to render a Model using a Basic Effect +description: Demonstrates how to load and render a model using the MonoGame Content Pipeline. +requireMSLicense: true +--- + +> It is assumed that an existing Windows game project is loaded in MonoGame. In this example, the project is called "CPModel." + +This example has three main parts: importing and processing the model, drawing the resultant managed object as a model with full lighting effect in the game, and enabling movement of the model with a game pad. + +## Adding a Model + +1. Right-click the **Content** project, click **Add**, and then click **Existing Item**. +2. Navigate to the correct folder and select the model to be added. + + > For this example, use the ship.fbx file. But you can use any model file you wish. + +3. Open the **Properties** window and verify that the correct importer and processor are specified. + + > For this example, the **Content Importer** is AutoDesk FBX - MonoGame Framework and the **Content Processor** is Model - MonoGame Framework. + +4. Save the solution. + +The remaining parts render the model and add some user control of the model. All code modifications for this part occur within the game1.cs file of the game project. + +## Rendering the model + +1. From Solution Explorer, double-click the game1.cs file. +2. Modify the **Game1** class by adding the following code at the beginning of the declaration. + + ```csharp + private Model gameShip; + ``` + + This member holds the ship model. + +3. Modify the **LoadGraphicsContent** method by adding the following code. + + ```csharp + gameShip = Content.Load("ship"); + ``` + + This code loads the model into the `gameShip` member (using [Load](xref:Microsoft.Xna.Framework.Content.ContentManager)). + +4. Create a new **private** method (called **DrawModel**) in the **Game1** class by adding the following code before the existing [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method. + + ```csharp + private void DrawModel(Model m) + { + Matrix[] transforms = new Matrix[m.Bones.Count]; + float aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio; + m.CopyAbsoluteBoneTransformsTo(transforms); + Matrix projection = + Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), + aspectRatio, 1.0f, 10000.0f); + Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 50.0f, Zoom), + Vector3.Zero, Vector3.Up); + + foreach (ModelMesh mesh in m.Meshes) + { + foreach (BasicEffect effect in mesh.Effects) + { + effect.EnableDefaultLighting(); + + effect.View = view; + effect.Projection = projection; + effect.World = gameWorldRotation * + transforms[mesh.ParentBone.Index] * + Matrix.CreateTranslation(Position); + } + mesh.Draw(); + } + } + ``` + + This code sets up the lighting effects for each sub-mesh of the model. The `gameWorldRotation` and `Zoom` variables are used for player control. This functionality is added later. + + > This render code is designed for only those models with a [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect). For custom effects, the inner `for-each` loop should be changed to use the [Effect](xref:Microsoft.Xna.Framework.Graphics.Effect) class instead of the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class. In addition, you must use [EffectParameter](xref:Microsoft.Xna.Framework.Graphics.EffectParameter) objects to manually set the world, view, and projection matrices. + +5. Modify the **Game1.Draw** method by replacing the following code `**`// TODO: Add your drawing code here` with the following code: + + ```csharp + DrawModel(gameShip); + ``` + + This initializes the model's effects before the model is rendered. + +6. Save the solution. + +At this point, the rendering code for the model is complete, but the user control code still needs implementation. + +## Moving the model + +1. Modify the **Game1** class by adding the following code after the `gameShip` declaration. + + ```csharp + private Vector3 Position = Vector3.One; + private float Zoom = 2500; + private float RotationY = 0.0f; + private float RotationX = 0.0f; + private Matrix gameWorldRotation; + ``` + + These members store the current position, zoom, and rotation values. In addition, the `gameWorldRotation` simplifies the `UpdateGamePad` code. + +2. Add a private method (called **UpdateGamePad**) before the call to [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_). + + ```csharp + private void UpdateGamePad() + { + GamePadState state = GamePad.GetState(PlayerIndex.One); + + if (state.Buttons.A == ButtonState.Pressed) + { + Exit(); + } + + Position.X += state.ThumbSticks.Left.X * 10; + Position.Y += state.ThumbSticks.Left.Y * 10; + Zoom += state.ThumbSticks.Right.Y * 10; + RotationY += state.ThumbSticks.Right.X; + if (state.DPad.Up == ButtonState.Pressed) + { + RotationX += 1.0f; + } + else if (state.DPad.Down == ButtonState.Pressed) + { + RotationX -= 1.0f; + } + gameWorldRotation = + Matrix.CreateRotationX(MathHelper.ToRadians(RotationX)) * + Matrix.CreateRotationY(MathHelper.ToRadians(RotationY)); + } + ``` + + This code implements an exit method for the game (pressing the **A** button on a GamePad), and updates the position members with the current input of the game controller. + +3. Modify the **Update** method by adding a call to `UpdateGamePad`, before the call to [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_). + + ```csharp + UpdateGamePad(); + ``` + + This code updates the state of the position variables with the latest input. + +4. Save the solution. + +Development is complete so you are ready to build and run the game. Control the ship location with the game pad, and exit by pressing the **A** button. + +## See Also + +[Adding Content to a Game](../Content_Pipeline/HowTo_GameContent_Add.md) +[Using Input](../input/index.md) diff --git a/articles/monogame/howto/graphics/HowTo_RotateMoveCamera.md b/articles/monogame/howto/graphics/HowTo_RotateMoveCamera.md new file mode 100644 index 0000000..64fe247 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_RotateMoveCamera.md @@ -0,0 +1,167 @@ +--- +title: How to rotate and move the Camera +description: Demonstrates how to rotate and move a camera in a 3D environment. You can rotate the camera about its y-axis, and move it forward and backward. You control the camera's position and orientation by using the directional keys on your keyboard or by using the D-pad of your gamepad. +--- + +# Rotating and Moving the Camera + +Demonstrates how to rotate and move a camera in a 3D environment. You can rotate the camera about its y-axis, and move it forward and backward. You control the camera's position and orientation by using the directional keys on your keyboard or by using the D-pad of your gamepad. + +## Overview + +This sample is based on several assumptions. + +* The camera will move frequently, so the camera view [Matrix](xref:Microsoft.Xna.Framework.Matrix) is created and set every time [Game](xref:Microsoft.Xna.Framework.Game) **Update** is called. +* The projection [Matrix](xref:Microsoft.Xna.Framework.Matrix) may also change frequently for effects such as zooming. +* You have added a model to the project. + +For the sake of simplicity, the sample limits the camera object to rotation about the y axis (vertical spin) and movement along the z axis (forward and backward). The following steps show you how to render the sample scene. + +### To render the sample scene + +1. Determine the location and orientation of the camera. + + ```csharp + static Vector3 avatarPosition = new Vector3(0, 0, -50); + static Vector3 cameraPosition = avatarPosition; + ``` + +2. Create a view matrix using the camera position, the camera orientation (also called the look at point), and the up vector using the **CreateLookAt** method of [Matrix](xref:Microsoft.Xna.Framework.Matrix). + + ```csharp + // Calculate the camera's current position. + + Matrix rotationMatrix = Matrix.CreateRotationY(avatarYaw); + + // Create a vector pointing the direction the camera is facing. + Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix); + + // Calculate the position the camera is looking at. + Vector3 cameraLookat = cameraPosition + transformedReference; + + // Set up the view matrix and projection matrix. + view = Matrix.CreateLookAt(cameraPosition, cameraLookat, new Vector3(0.0f, 1.0f, 0.0f)); + ``` + +3. Create a perspective matrix using the near and far clipping planes and the aspect ratio using the CreatePerspectiveFieldOfView method of [Matrix](xref:Microsoft.Xna.Framework.Matrix). + + ```csharp + proj = Matrix.CreatePerspectiveFieldOfView(viewAngle, graphics.GraphicsDevice.Viewport.AspectRatio, nearClip, farClip); + ``` + +4. In the [Game](xref:Microsoft.Xna.Framework.Game) **Draw** method of your game, initialize a [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) object with the world, view, and projection matrices and render all of the 3D objects in the scene. + + ```csharp + void DrawModel(Model model, Matrix world, Texture2D texture) + { + foreach (ModelMesh mesh in model.Meshes) + { + foreach (BasicEffect be in mesh.Effects) + { + be.Projection = proj; + be.View = view; + be.World = world; + be.Texture = texture; + be.TextureEnabled = true; + } + mesh.Draw(); + } + } + ``` + +## Rotating and Moving a Camera + +### To rotate and move the camera + +1. Determine the location and orientation of the camera. + + ```csharp + static Vector3 avatarPosition = new Vector3(0, 0, -50); + static Vector3 cameraPosition = avatarPosition; + ``` + +2. Determine the reference [Vector3](xref:Microsoft.Xna.Framework.Vector3) to which the rotation of the camera is relative. + + The direction should not change during the game, and usually it will be (0, 0, 1) or (0, 0, −1). + + ```csharp + // Set the direction the camera points without rotation. + Vector3 cameraReference = new Vector3(0, 0, 1); + ``` + +3. Create a rotation [Matrix](xref:Microsoft.Xna.Framework.Matrix) for the amount of rotation for the camera. + + Because the camera is limited to one axis of rotation, this matrix represents the rotation of the camera around its own y-axis. Use **CreateRotationY** to create a rotation [Matrix](xref:Microsoft.Xna.Framework.Matrix) representing the rotation around the y-axis. + + ```csharp + Matrix rotationMatrix = Matrix.CreateRotationY(avatarYaw); + ``` + +4. Use the [Vector3](xref:Microsoft.Xna.Framework.Vector3) **Transform** and the rotation [Matrix](xref:Microsoft.Xna.Framework.Matrix) to transform the reference [vector](xref:Microsoft.Xna.Framework.Vector3). + + This represents the direction the camera is pointing in transformed (or view) space. + + ```csharp + // Create a vector pointing the direction the camera is facing. + Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix); + ``` + +5. Add the camera's current position to the transformed direction [vector](xref:Microsoft.Xna.Framework.Vector3). + + The result is the position to which the camera is pointing. + + ```csharp + // Calculate the position the camera is looking at. + Vector3 cameraLookat = cameraPosition + transformedReference; + ``` + +6. Create a new view [Matrix](xref:Microsoft.Xna.Framework.Matrix) using **CreateLookAt**. + +7. Use [Matrix.CreateLookAt](xref:Microsoft.Xna.Framework.Matrix) to pass the camera's current position and the transformed direction vector. + + The third parameter of **CreateLookAt** is the up direction of the camera. Typically, it is [Vector3](xref:Microsoft.Xna.Framework.Vector3) **Up** (0, 1, 0). This matrix [Matrix](xref:Microsoft.Xna.Framework.Matrix) controls how world coordinates are transformed to camera coordinates. + + ```csharp + // Set up the view matrix and projection matrix. + view = Matrix.CreateLookAt(cameraPosition, cameraLookat, new Vector3(0.0f, 1.0f, 0.0f)); + ``` + +8. Use **CreatePerspectiveFieldOfView** to create a new projection [Matrix](xref:Microsoft.Xna.Framework.Matrix). + + This [Matrix](xref:Microsoft.Xna.Framework.Matrix) controls how camera coordinate values are transformed to screen coordinates. + + The first parameter is the field of view of the projection [Matrix](xref:Microsoft.Xna.Framework.Matrix) expressed in radians. A typical field of view of 45 degrees would be expressed as π/4 radians. The second parameter is the aspect ratio of the projection [Matrix](xref:Microsoft.Xna.Framework.Matrix); it corrects for the difference in width and height of a viewspace. The third and fourth parameters specify the near and far distances at which the objects will be visible. + + ```csharp + // Set distance from the camera of the near and far clipping planes. + static float nearClip = 1.0f; + static float farClip = 2000.0f; + ``` + +9. Loop through each 3D model to be rendered using the projection matrix and view matrix created above. + + An identity matrix simplifies the code for the world matrix. + + ```csharp + void DrawModel(Model model, Matrix world, Texture2D texture) + { + foreach (ModelMesh mesh in model.Meshes) + { + foreach (BasicEffect be in mesh.Effects) + { + be.Projection = proj; + be.View = view; + be.World = world; + be.Texture = texture; + be.TextureEnabled = true; + } + mesh.Draw(); + } + } + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Rotate_Sprite.md b/articles/monogame/howto/graphics/HowTo_Rotate_Sprite.md new file mode 100644 index 0000000..84df67a --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Rotate_Sprite.md @@ -0,0 +1,100 @@ +--- +title: Rotating a Sprite +description: Demonstrates how to rotate a sprite around its center. +--- + +# Rotating a Sprite + +Demonstrates how to rotate a sprite around its center. + +## Drawing a Rotated Sprite + +1. Follow the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). + +2. Determine the screen location of the sprite, and the point within the texture that will serve as the origin. + By default, the origin of a texture is (0,0), the upper-left corner. When you draw a sprite, the origin point in the texture is placed on the screen coordinate specified by the _at_ parameter. In this example, the origin is the center of the texture, and the screen position is the center of the screen. + + ```csharp + private Texture2D SpriteTexture; + private Vector2 origin; + private Vector2 screenpos; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + SpriteTexture = Content.Load("ship"); + Viewport viewport = graphics.GraphicsDevice.Viewport; + origin.X = SpriteTexture.Width / 2; + origin.Y = SpriteTexture.Height / 2; + screenpos.X = viewport.Width / 2; + screenpos.Y = viewport.Height / 2; + } + ``` + +3. In your [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method, determine the rotation angle to use for the sprite. + + The angle is specified in radians, and it can be greater than two times π, but does not need to be. + + ```csharp + private float RotationAngle; + protected override void Update(GameTime gameTime) + { + // Allows the game to exit + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) + this.Exit(); + + if (Keyboard.GetState().IsKeyDown(Keys.Escape)) + this.Exit(); + + // The time since Update was called last. + float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; + + // TODO: Add your game logic here. + RotationAngle += elapsed; + float circle = MathHelper.Pi * 2; + RotationAngle = RotationAngle % circle; + + base.Update(gameTime); + } + ``` + +4. In your [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, call [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) with the texture, angle, screen position, and origin of the texture. + + ```csharp + protected override void Draw(GameTime gameTime) + { + graphics.GraphicsDevice.Clear(Color.CornflowerBlue); + + // TODO: Add your drawing code here + spriteBatch.Begin(); + spriteBatch.Draw(SpriteTexture, screenpos, null, Color.White, RotationAngle, + origin, 1.0f, SpriteEffects.None, 0f); + spriteBatch.End(); + + base.Draw(gameTime); + } + ``` + +5. When all the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Rotate_Sprite_Group.md b/articles/monogame/howto/graphics/HowTo_Rotate_Sprite_Group.md new file mode 100644 index 0000000..90c497d --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Rotate_Sprite_Group.md @@ -0,0 +1,131 @@ +--- +title: Rotating a Group of Sprites +description: Demonstrates how to rotate a group of sprites around a single point. +--- + +# Rotating a Group of Sprites + +Demonstrates how to rotate a group of sprites around a single point. + +## Drawing a Rotated Group of Sprites + +1. Follow the steps of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). + +2. Create one set of [Vector2](xref:Microsoft.Xna.Framework.Vector2) objects that represents the unrotated positions of the sprites and one set to hold the rotated values. + + ```csharp + private Vector2[] myVectors; + private Vector2[] drawVectors; + protected override void Initialize() + { + myVectors = new Vector2[9]; + drawVectors = new Vector2[9]; + + base.Initialize(); + } + ``` + +3. After loading the sprite, calculate the positions of the unrotated group of sprites based on the sprite's size. + + ```csharp + private Texture2D SpriteTexture; + private Vector2 origin; + private Vector2 screenpos; + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + SpriteTexture = Content.Load("ship"); + origin.X = SpriteTexture.Width / 2; + origin.Y = SpriteTexture.Height / 2; + Viewport viewport = graphics.GraphicsDevice.Viewport; + screenpos.X = viewport.Width / 2; + screenpos.Y = viewport.Height / 2; + } + ``` + +4. In your [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method, copy the unrotated vectors and determine the screen position around which all the sprites will rotate. + + ```csharp + private float RotationAngle = 0f; + private Matrix rotationMatrix = Matrix.Identity; + protected override void Update(GameTime gameTime) + { + ... + float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; + + RotationAngle += elapsed; + float circle = MathHelper.Pi * 2; + RotationAngle = RotationAngle % circle; + + // Copy and rotate the sprite positions. + drawVectors = (Vector2[])myVectors.Clone(); + + RotatePoints(ref screenpos, RotationAngle, ref drawVectors); + + base.Update(gameTime); + } + ``` + + Transform each vector using a rotation matrix created for the rotation angle. + +5. To rotate around the origin, transform each vector relative to the origin by subtracting the origin vector. + +6. Add the origin vector to the transformed vector to create the final rotated vector. + + ```csharp + private static void RotatePoints(ref Vector2 origin, float radians, ref Vector2[] Vectors) + { + Matrix myRotationMatrix = Matrix.CreateRotationZ(radians); + + for (int i = 0; i < 9; i++) + { + // Rotate relative to origin. + Vector2 rotatedVector = + Vector2.Transform(Vectors[i] - origin, myRotationMatrix); + + // Add origin to get final location. + Vectors[i] = rotatedVector + origin; + } + } + ``` + +7. Draw each sprite using the rotated vectors as screen locations. + + ```csharp + private void DrawPoints() + { + // Draw using manually rotated vectors + spriteBatch.Begin(); + for (int i = 0; i < drawVectors.Length; i++) + spriteBatch.Draw(SpriteTexture, drawVectors[i], null, + Color.White, RotationAngle, origin, 1.0f, + SpriteEffects.None, 0f); + spriteBatch.End(); + } + ``` + +8. When all the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End). + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Scale_Sprite.md b/articles/monogame/howto/graphics/HowTo_Scale_Sprite.md new file mode 100644 index 0000000..b4da0a3 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Scale_Sprite.md @@ -0,0 +1,151 @@ +--- +title: Scaling a Sprite +description: Demonstrates how to scale a sprite using a uniform scale. +--- + +# Scaling a Sprite + +Demonstrates how to scale a sprite using a uniform scale. + +## Drawing a Scaled Sprite with a uniform scale + +1. Follow the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). + +2. In your **Update** method, determine how your sprite will be scaled. + + The normal size of the sprite is multiplied by the scale specified. For example, a value of 1.0 draws the sprite full size, where 0.5 will draw it half-sized and 2.0 will draw it at twice its original size. + + ```csharp + protected float scale = 1f; + protected override void Update(GameTime gameTime) + { + ... + + #if DESKTOP + if (Keyboard.GetState().IsKeyDown(Keys.Escape)) + this.Exit(); + #endif + + // The time since Update was called last. + float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; + + // TODO: Add your game logic here. + scale += elapsed; + scale = scale % 6; + + base.Update(gameTime); + } + ``` + +3. When drawing the sprite, specify the scale of the sprite as a parameter to draw. + + Specifying a floating-point scale parameter scales the sprite evenly in both the x and y directions. + + ```csharp + protected virtual void DrawForeground(SpriteBatch batch) + { + Rectangle safeArea = GetTitleSafeArea(.8f); + Vector2 position = new Vector2(safeArea.X, safeArea.Y); + batch.Begin(); + batch.Draw(SpriteTexture, position, null, + Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); + batch.End(); + } + ``` + +4. When all the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + +### To draw a scaled sprite using a nonuniform scale + +1. Follow the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). +2. In your **Update** method, determine how your sprite will be scaled along each axis and store those values in a [Vector2](xref:Microsoft.Xna.Framework.Vector2) object. + + ```csharp + protected Vector2 nonuniformscale = Vector2.One; + protected override void Update(GameTime gameTime) + { + base.Update(gameTime); + float basescale = nonuniformscale.Y; + basescale += (float)gameTime.ElapsedGameTime.TotalSeconds; + basescale = basescale % 6; + nonuniformscale.Y = basescale; + nonuniformscale.X = basescale * .8f; + } + ``` + +3. When drawing the sprite, specify the scale of the sprite using the [Vector2](xref:Microsoft.Xna.Framework.Vector2) object that you updated earlier. + + Specifying a [Vector2](xref:Microsoft.Xna.Framework.Vector2) scales the sprite independently in both the x and y directions. + + ```csharp + protected override void DrawForeground(SpriteBatch batch) + { + Rectangle safeArea = GetTitleSafeArea(.8f); + Vector2 position = new Vector2(safeArea.X, safeArea.Y); + batch.Begin(); + batch.Draw(SpriteTexture, position, null, Color.White, 0, Vector2.Zero, + nonuniformscale, SpriteEffects.None, 0); + batch.End(); + } + ``` + +4. When all of the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + +### To draw a scaled sprite using a destination rectangle + +1. Follow the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). + +2. In your **Update** method, construct a rectangle that defines where on screen the sprite will be drawn. + + This rectangle does not need to be the same shape or size as the original sprite. Each dimension of the sprite is scaled independently to fit the destination rectangle. + + ```csharp + protected Rectangle destrect; + protected override void Update(GameTime gameTime) + { + destrect = new Rectangle(); + Rectangle safeArea = GetTitleSafeArea(.8f); + destrect.X = safeArea.X; + destrect.Y = safeArea.Y; + destrect.Width = (int)scale * 100; + destrect.Height = (int)scale * 80; + base.Update(gameTime); + } + ``` + +3. When drawing the sprite, specify the destination rectangle as a parameter to [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_). + + The sprite will be drawn, filling the destination rectangle. + + ```csharp + protected override void DrawForeground(SpriteBatch batch) + { + batch.Begin(); + batch.Draw(SpriteTexture, destrect, Color.White); + batch.End(); + } + ``` + +4. When all of the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Scale_Sprites_Matrix.md b/articles/monogame/howto/graphics/HowTo_Scale_Sprites_Matrix.md new file mode 100644 index 0000000..f0a253a --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Scale_Sprites_Matrix.md @@ -0,0 +1,123 @@ +--- +title: Scaling Sprites Based On Screen Size +description: Demonstrates how to scale sprites using a matrix that is created based on the viewport width. +--- + +# Scaling Sprites Based On Screen Size + +Demonstrates how to scale sprites using a matrix that is created based on the viewport width. + +## Scaling Sprites Based on Screen Size + +1. Use the [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight) and [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth) properties of [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) during your game's [Initialize](xref:Microsoft.Xna.Framework.Game.Initialize) to set the default screen size of your game. + +2. In your [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) method, use [Matrix.CreateScale](xref:Microsoft.Xna.Framework.Matrix#Microsoft_Xna_Framework_Matrix_CreateScale_System_Single_) to create a scaling matrix. + + This matrix is recreated any time the resolution of the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) changes. + + Because you are scaling sprites, you should use only the x and y parameters to create the scaling matrix. Scaling the depth of sprites can result in their depth shifting above 1.0. If that happens, they will not render. + + ```csharp + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + ... + + // Default resolution is 800x600; scale sprites up or down based on + // current viewport + float screenscale = + (float)graphics.GraphicsDevice.Viewport.Width / 800f; + // Create the scale transform for Draw. + // Do not scale the sprite depth (Z=1). + SpriteScale = Matrix.CreateScale(screenscale, screenscale, 1); + } + ``` + +3. In your [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method, determine whether the game needs to change screen resolution. + + This example uses game pad buttons to switch between two resolutions. + + ```csharp + protected override void Update(GameTime gameTime) + { + ... + // Change the resolution dynamically based on input + if (GamePad.GetState(PlayerIndex.One).Buttons.A == + ButtonState.Pressed) + { + graphics.PreferredBackBufferHeight = 768; + graphics.PreferredBackBufferWidth = 1024; + graphics.ApplyChanges(); + } + if (GamePad.GetState(PlayerIndex.One).Buttons.B == + ButtonState.Pressed) + { + graphics.PreferredBackBufferHeight = 600; + graphics.PreferredBackBufferWidth = 800; + graphics.ApplyChanges(); + } + + if (Keyboard.GetState().IsKeyDown(Keys.A)) + { + graphics.PreferredBackBufferHeight = 768; + graphics.PreferredBackBufferWidth = 1024; + graphics.ApplyChanges(); + } + if (Keyboard.GetState().IsKeyDown(Keys.B)) + { + graphics.PreferredBackBufferHeight = 600; + graphics.PreferredBackBufferWidth = 800; + graphics.ApplyChanges(); + } + + base.Update(gameTime); + } + ``` + +4. In your [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__), passing the scaling matrix created in [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent). + +5. Draw your scene normally, then call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End). + + All of the sprites you draw will be scaled according to the matrix. + + ```csharp + protected override void Draw(GameTime gameTime) + { + ... + // Initialize the batch with the scaling matrix + spriteBatch.Begin(); + // Draw a sprite at each corner + for (int i = 0; i < spritepos.Length; i++) + { + spriteBatch.Draw(square, spritepos[i], null, Color.White, + rotation, origin, scale, SpriteEffects.None, depth); + } + spriteBatch.End(); + base.Draw(gameTime); + } + ``` + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) +[Matrix.CreateScale](xref:Microsoft.Xna.Framework.Matrix#Microsoft_Xna_Framework_Matrix_CreateScale_System_Single_) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_ScriptedCamera.md b/articles/monogame/howto/graphics/HowTo_ScriptedCamera.md new file mode 100644 index 0000000..f282276 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_ScriptedCamera.md @@ -0,0 +1,143 @@ +--- +title: How to move the Camera on a Curve +description: Demonstrates how to use the Curve and CurveKey classes to move a camera along the shape of a curve. +--- + +# Moving the Camera on a Curve + +Demonstrates how to use the [Curve](xref:Microsoft.Xna.Framework.Curve) and [CurveKey](xref:Microsoft.Xna.Framework.CurveKey) classes to move a camera along the shape of a curve. + +Using [Curve](xref:Microsoft.Xna.Framework.Curve)s allows a path to be defined by a small number of control points with the [Curve](xref:Microsoft.Xna.Framework.Curve)s calculating the points on the path between the control points. + +## Scripting the Camera to Follow a Curve + +### To script camera movement + +1. Create an instance of the [Curve](xref:Microsoft.Xna.Framework.Curve) class for each component being scripted. + + In this case, you need two sets of three curves. One is for each of the x, y, and z components of the camera's position, and the other is for the position at which the camera is looking (the "look-at" position). + + ```csharp + class Curve3D + { + + public Curve curveX = new Curve(); + public Curve curveY = new Curve(); + public Curve curveZ = new Curve(); + ... + } + ``` + +2. Set the **PreLoop** and **PostLoop** type of each [Curve](xref:Microsoft.Xna.Framework.Curve). + + The **PreLoop** and **PostLoop** types determine how the curve will interpret positions before the first key or after the last key. In this case, the values will be set to [CurveLoopType.Oscillate](xref:Microsoft.Xna.Framework.CurveLoopType). Values past the ends of the curve will change direction and head toward the opposite side of the curve. + + ```csharp + curveX.PostLoop = CurveLoopType.Oscillate; + curveY.PostLoop = CurveLoopType.Oscillate; + curveZ.PostLoop = CurveLoopType.Oscillate; + + curveX.PreLoop = CurveLoopType.Oscillate; + curveY.PreLoop = CurveLoopType.Oscillate; + curveZ.PreLoop = CurveLoopType.Oscillate; + ``` + +3. Add [CurveKey](xref:Microsoft.Xna.Framework.CurveKey)s to the [Curve](xref:Microsoft.Xna.Framework.Curve)s. + +4. Specify the time each [CurveKey](xref:Microsoft.Xna.Framework.CurveKey) should be reached and the camera position when the [CurveKey](xref:Microsoft.Xna.Framework.CurveKey) is reached. + + In this case, each point in time will have three [CurveKey](xref:Microsoft.Xna.Framework.CurveKey)s associated with it – one for each of the x, y, and z coordinates of the point on the [Curve](xref:Microsoft.Xna.Framework.Curve). + + ```csharp + public void AddPoint(Vector3 point, float time) + { + curveX.Keys.Add(new CurveKey(time, point.X)); + curveY.Keys.Add(new CurveKey(time, point.Y)); + curveZ.Keys.Add(new CurveKey(time, point.Z)); + } + ``` + +5. Loop through each [Curve](xref:Microsoft.Xna.Framework.Curve) setting the **TangentIn** and **TangentOut** of each [CurveKey](xref:Microsoft.Xna.Framework.CurveKey). + + The tangents of the [CurveKey](xref:Microsoft.Xna.Framework.CurveKey)s control the shape of the [Curve](xref:Microsoft.Xna.Framework.Curve). Setting the tangents of the [CurveKey](xref:Microsoft.Xna.Framework.CurveKey)s to the slope between the previous and next [CurveKey](xref:Microsoft.Xna.Framework.CurveKey) will give a curve that moves smoothly through each point on the curve. + + ```csharp + public void SetTangents() + { + CurveKey prev; + CurveKey current; + CurveKey next; + int prevIndex; + int nextIndex; + for (int i = 0; i < curveX.Keys.Count; i++) + { + prevIndex = i - 1; + if (prevIndex < 0) prevIndex = i; + + nextIndex = i + 1; + if (nextIndex == curveX.Keys.Count) nextIndex = i; + + prev = curveX.Keys[prevIndex]; + next = curveX.Keys[nextIndex]; + current = curveX.Keys[i]; + SetCurveKeyTangent(ref prev, ref current, ref next); + curveX.Keys[i] = current; + prev = curveY.Keys[prevIndex]; + next = curveY.Keys[nextIndex]; + current = curveY.Keys[i]; + SetCurveKeyTangent(ref prev, ref current, ref next); + curveY.Keys[i] = current; + + prev = curveZ.Keys[prevIndex]; + next = curveZ.Keys[nextIndex]; + current = curveZ.Keys[i]; + SetCurveKeyTangent(ref prev, ref current, ref next); + curveZ.Keys[i] = current; + } + } + ``` + +6. Add code to evaluate the x, y, and z coordinates of the [Curve](xref:Microsoft.Xna.Framework.Curve)s at any given time by passing the elapsed time to the **Evaluate** method of each of the [Curve](xref:Microsoft.Xna.Framework.Curve)s. + + ```csharp + public Vector3 GetPointOnCurve(float time) + { + Vector3 point = new Vector3(); + point.X = curveX.Evaluate(time); + point.Y = curveY.Evaluate(time); + point.Z = curveZ.Evaluate(time); + return point; + } + ``` + +7. Create a variable to track the amount of time that has passed since the camera started moving. + + ```csharp + double time; + ``` + +8. In [Game](xref:Microsoft.Xna.Framework.Game) **Update**, set the camera's position and look-at position based on the elapsed time since the camera started moving, and then set the camera's view and projection matrices as in [Rotating and Moving the Camera](HowTo_RotateMoveCamera.md). + + ```csharp + // Calculate the camera's current position. + Vector3 cameraPosition = + cameraCurvePosition.GetPointOnCurve((float)time); + Vector3 cameraLookat = + cameraCurveLookat.GetPointOnCurve((float)time); + ``` + +9. In [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_), use [gameTime.ElapsedGameTime.TotalMilliseconds](xref:Microsoft.Xna.Framework.GameTime.ElapsedGameTime) to increment the time since the camera started moving. + + ```csharp + time += gameTime.ElapsedGameTime.TotalMilliseconds; + ``` + +## See Also + +[Rotating and Moving the Camera](HowTo_RotateMoveCamera.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Select_and_Object_with_a_Mouse.md b/articles/monogame/howto/graphics/HowTo_Select_and_Object_with_a_Mouse.md new file mode 100644 index 0000000..13a8192 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Select_and_Object_with_a_Mouse.md @@ -0,0 +1,72 @@ +--- +title: Selecting an Object with a Mouse +description: Demonstrates how to check whether the mouse is positioned over a 3D object by creating a ray starting at the camera's near clipping plane and ending at its far clipping plane. +--- + +# Selecting an Object with a Mouse + +Demonstrates how to check whether the mouse is positioned over a 3D object by creating a ray starting at the camera's near clipping plane and ending at its far clipping plane. + +> [!NOTE] +> This example applies only to Windows or mobile development. The [Mouse](xref:Microsoft.Xna.Framework.Input.Mouse) and [MouseState](xref:Microsoft.Xna.Framework.Input.MouseState) objects are not supported on consoles. + +## Detecting Whether a User Clicked a 3D Object + +### To check whether the mouse is positioned over a 3D object + +1. Get the current state of the mouse by using [GetState](xref:Microsoft.Xna.Framework.Input.Mouse). + + ``` csharp + MouseState mouseState = Mouse.GetState(); + ``` + +2. Get the current screen coordinates of the mouse from [X](xref:Microsoft.Xna.Framework.Input.Mouse) and [Y](xref:Microsoft.Xna.Framework.Input.Mouse). + + ``` csharp + int mouseX = mouseState.X; + int mouseY = mouseState.Y; + ``` + +3. Using [Viewport.Unproject](xref:Microsoft.Xna.Framework.Graphics.Viewport#Microsoft_Xna_Framework_Graphics_Viewport_Unproject_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_), determine points in world space on the near and far clipping planes. For the point on the near plane, pass a source vector with x and y set to the mouse position, and z set to 0. + +4. For the point on the far plane, pass a source vector with x and y set to the mouse position, and z set to 1. + +5. Create a translation matrix for a point that is the origin, (0,0,0). + +6. For both points, pass [Viewport.Unproject](xref:Microsoft.Xna.Framework.Graphics.Viewport#Microsoft_Xna_Framework_Graphics_Viewport_Unproject_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_Microsoft_Xna_Framework_Matrix_) the current projection matrix, the view matrix. + + ``` csharp + Vector3 nearsource = new Vector3((float)mouseX, (float)mouseY, 0f); + Vector3 farsource = new Vector3((float)mouseX, (float)mouseY, 1f); + + Matrix world = Matrix.CreateTranslation(0, 0, 0); + + Vector3 nearPoint = GraphicsDevice.Viewport.Unproject(nearsource, + proj, view, world); + + Vector3 farPoint = GraphicsDevice.Viewport.Unproject(farsource, + proj, view, world); + ``` + +7. Create a [Ray](xref:Microsoft.Xna.Framework.Ray) whose origin is at the near point and whose direction points to the far point. + + ``` csharp + // Create a ray from the near clip plane to the far clip plane. + Vector3 direction = farPoint - nearPoint; + direction.Normalize(); + Ray pickRay = new Ray(nearPoint, direction); + ``` + +8. Loop through each object in the scene using the [Intersects](xref:Microsoft.Xna.Framework.Ray) method to check whether the [Ray](xref:Microsoft.Xna.Framework.Ray) intersects each object. + +9. If the [Ray](xref:Microsoft.Xna.Framework.Ray) intersects an object, check whether it is the closest object intersected so far. If it is, store the object and the distance at which it was intersected, replacing any previously stored object. + +10. When you completely loop through the objects, the last object stored will be the closest object underneath the area the user clicked. + +## See Also + +[Rotating and Moving the Camera](HowTo_RotateMoveCamera.md) + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Test_for_Collisions.md b/articles/monogame/howto/graphics/HowTo_Test_for_Collisions.md new file mode 100644 index 0000000..c23fe1c --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Test_for_Collisions.md @@ -0,0 +1,90 @@ +--- +title: Testing for Collisions +description: Demonstrates how to use the BoundingSphere class to check whether two models are colliding. +--- + +# Testing for Collisions + +Demonstrates how to use the [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere) class to check whether two models are colliding. + +## Detecting Whether Two Models Collide + +### To check whether two objects are colliding + +1. Track the position of a model as it moves about the game world. + + ``` csharp + struct WorldObject + { + public Vector3 position; + public Vector3 velocity; + public Model model; + public Texture2D texture2D; + public Vector3 lastPosition; + public void MoveForward() + { + lastPosition = position; + position += velocity; + } + public void Backup() + { + position -= velocity; + } + public void ReverseVelocity() + { + velocity.X = -velocity.X; + } + } + ``` + +2. Make a nested loop with the first model's meshes as the outer loop and the second model's meshes as the inner loop. + +3. Inside the loop, follow these steps. + + 1. Get the bounding sphere for the current mesh of the first model and the current mesh of the second model. + + 2. Offset the bounding spheres by the current positions of the models. + + 3. Call the [BoundingSphere.Intersects](xref:Microsoft.Xna.Framework.BoundingSphere) method to check the pairs of bounding spheres for collision. + + If the method returns **true**, the objects are colliding. + + 4. If the models are colliding, break out of the loop. + + ``` csharp + static void CheckForCollisions(ref WorldObject c1, ref WorldObject c2) + { + for (int i = 0; i < c1.model.Meshes.Count; i++) + { + // Check whether the bounding boxes of the two cubes intersect. + BoundingSphere c1BoundingSphere = c1.model.Meshes[i].BoundingSphere; + c1BoundingSphere.Center += c1.position; + + for (int j = 0; j < c2.model.Meshes.Count; j++) + { + BoundingSphere c2BoundingSphere = c2.model.Meshes[j].BoundingSphere; + c2BoundingSphere.Center += c2.position; + + if (c1BoundingSphere.Intersects(c2BoundingSphere)) + { + c2.ReverseVelocity(); + c1.Backup(); + c1.ReverseVelocity(); + return; + } + } + } + } + ``` + +## See Also + +[Rotating and Moving the Camera](HowTo_RotateMoveCamera.md) + +### Concepts + +[Bounding Volumes and Collisions](../HowTo_CollisionDetectionOverview.md) + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Tile_Sprites.md b/articles/monogame/howto/graphics/HowTo_Tile_Sprites.md new file mode 100644 index 0000000..079a70d --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Tile_Sprites.md @@ -0,0 +1,60 @@ +--- +title: Tiling a Sprite +description: Demonstrates how to draw a sprite repeatedly in the x and y directions in one Draw call +--- + +# Tiling a Sprite + +Demonstrates how to draw a sprite repeatedly in the x and y directions in one [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) call. + +![Tiled Sprite](../images/graphics_sprite_tiled.jpg) + +This sample uses a texture addressing mode to duplicate a texture across the area defined by [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_). Other address modes, such as mirroring, can create interesting results. + +## Drawing a Tiled a Sprite + +1. Follow the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). +2. In the [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, create a [Rectangle](xref:Microsoft.Xna.Framework.Rectangle) to define the area to fill. +3. Call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) to set the sprite state. + + The destination [Rectangle](xref:Microsoft.Xna.Framework.Rectangle) can be any size. In this example, the width and height of the destination rectangle are integer multiples of the source sprite. This will cause the sprite texture to be tiled, or drawn several times, to fill the destination area. + + ```csharp + spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.Opaque, SamplerState.LinearWrap, + DepthStencilState.Default, RasterizerState.CullNone); + ``` + +4. Call [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) with the sprite, the destination rectangle, and other relevant parameters. + + ```csharp + spriteBatch.Draw(spriteTexture, Vector2.Zero, destRect, color, 0, Vector2.Zero, 1, SpriteEffects.None, 0); + ``` + +5. Call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + + ```csharp + spriteBatch.End(); + ``` + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) +[SpriteSortMode](xref:Microsoft.Xna.Framework.Graphics.SpriteSortMode) +[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_Tint_Sprite.md b/articles/monogame/howto/graphics/HowTo_Tint_Sprite.md new file mode 100644 index 0000000..51458d9 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_Tint_Sprite.md @@ -0,0 +1,69 @@ +--- +title: Tinting a Sprite +description: Demonstrates how to tint a sprite using a Color value. +--- + +# Tinting a Sprite + +Demonstrates how to tint a sprite using a [Color](xref:Microsoft.Xna.Framework.Color) value. + +## Drawing a Tinted Sprite + +1. Follow the procedures of [Drawing a Sprite](HowTo_Draw_A_Sprite.md). +2. In the [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method, determine how to tint the sprite. + + In this example, the value of the game pad thumbsticks determine the Red, Green, Blue, and Alpha values to apply to the sprite. + + ```csharp + protected Color tint; + protected override void Update(GameTime gameTime) + { + ... + GamePadState input = GamePad.GetState(PlayerIndex.One); + tint = new Color(GetColor(input.ThumbSticks.Left.X), + GetColor(input.ThumbSticks.Left.Y), + GetColor(input.ThumbSticks.Right.X), + GetColor(input.ThumbSticks.Right.Y)); + + base.Update(gameTime); + } + ``` + +3. In the [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, pass the color value created in [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) to [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_). + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + spriteBatch.Begin(); + spriteBatch.Draw(SpriteTexture, position, tint); + spriteBatch.End(); + + base.Draw(gameTime); + } + ``` + +4. When all of the sprites have been drawn, call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) on your [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object. + +## See Also + +### Tasks + +[Drawing a Sprite](HowTo_Draw_A_Sprite.md) + +#### Concepts + +[What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md) + +#### Reference + +[SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) +[SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_)[Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) +[Color](xref:Microsoft.Xna.Framework.Color) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_TransformPoint.md b/articles/monogame/howto/graphics/HowTo_TransformPoint.md new file mode 100644 index 0000000..7e6115e --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_TransformPoint.md @@ -0,0 +1,46 @@ +--- +title: How to transform a Point +description: This example demonstrates how to use the Vector3 and Matrix classes to transform a point. A matrix transform can include scaling, rotating, and translating information. +--- + +# Transforming a Point + +This example demonstrates how to use the [Vector3](xref:Microsoft.Xna.Framework.Vector3) and [Matrix](xref:Microsoft.Xna.Framework.Matrix) classes to transform a point. A matrix transform can include scaling, rotating, and translating information. + +## Transforming a Point with a Matrix + +### To transform a point + +1. Create a [Matrix](xref:Microsoft.Xna.Framework.Matrix) by using **CreateRotationY** or one of the other **Create** methods. +2. Pass the point and the [Matrix](xref:Microsoft.Xna.Framework.Matrix) to the [Vector3.Transform](xref:Microsoft.Xna.Framework.Vector3) method. + +```csharp +static Vector3 RotatePointOnYAxis(Vector3 point, float angle) +{ + // Create a rotation matrix that represents a rotation of angle radians. + Matrix rotationMatrix = Matrix.CreateRotationY(angle); + + // Apply the rotation matrix to the point. + Vector3 rotatedPoint = Vector3.Transform(point, rotationMatrix); + + return rotatedPoint; +} +``` + +## See Also + +### Matrix Creation Methods + +[Matrix](xref:Microsoft.Xna.Framework.Matrix) + +* CreateRotationX +* CreateRotationY +* CreateRotationZ +* CreateScale +* CreateTranslation + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_UseACustomVertex.md b/articles/monogame/howto/graphics/HowTo_UseACustomVertex.md new file mode 100644 index 0000000..9656dc5 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_UseACustomVertex.md @@ -0,0 +1,147 @@ +--- +title: How to create a Custom Vertex Declaration +description: Demonstrates how to create a custom vertex declaration and use it to render a 3D object. +--- + +# Creating a Custom Vertex Declaration + +Demonstrates how to create a custom vertex declaration and use it to render a 3D object. + +![Custom Vertex Example](../images/graphics_custom_vertex.png) + +Game Studio includes a few predefined classes for common vertex buffer declarations such as [VertexPositionColor](xref:Microsoft.Xna.Framework.Graphics.VertexPositionColor) and [VertexPositionColorTexture](xref:Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture). If you need to create a vertex buffer declaration that includes additional user-defined types, create a custom vertex declaration. + +A custom vertex declaration is a class that implements fully customizable per-vertex data. Furthermore, if you derive the class from [IVertexType](xref:Microsoft.Xna.Framework.Graphics.IVertexType), you will not need to create a vertex declaration when creating your vertex buffer or drawing the geometry. + +## To create a custom vertex declaration + +1. Declare a structure that derives from [IVertexType](xref:Microsoft.Xna.Framework.Graphics.IVertexType). + + ```csharp + public struct CustomVertex1 : IVertexType + ``` + +2. Add members to the struct that describe the per-vertex data. + + This example uses position as a [Vector3 Structure](xref:Microsoft.Xna.Framework.Vector3) type, a texture coordinate using a [Vector2 Structure](xref:Microsoft.Xna.Framework.Vector2) type, and a vertex declaration using the [VertexDeclaration](xref:Microsoft.Xna.Framework.Graphics.VertexDeclaration) type. + + ```csharp + Vector3 vertexPosition; + Vector2 vertexTextureCoordinate; + + public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration + ( + new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), + new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0) + ); + ``` + +3. Implement a constructor and public accessor methods. + + ```csharp + //The constructor for the custom vertex. This allows similar + //initialization of custom vertex arrays as compared to arrays of a + //standard vertex type, such as VertexPositionColor. + public CustomVertex1(Vector3 pos, Vector2 textureCoordinate) + { + vertexPosition = pos; + vertexTextureCoordinate = textureCoordinate; + } + + //Public methods for accessing the components of the custom vertex. + public Vector3 Position + { + get { return vertexPosition; } + set { vertexPosition = value; } + } + + public Vector2 TextureCoordinate + { + get { return vertexTextureCoordinate; } + set { vertexTextureCoordinate = value; } + } + ``` + +4. Implement a non-public method for accessing the vertex declaration. + + ```csharp + VertexDeclaration IVertexType.VertexDeclaration + { + get { return VertexDeclaration; } + } + ``` + +5. Create a built-in effect to render the object with a texture using the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class as demonstrated in [Creating a Basic Effect](./HowTo_Create_a_BasicEffect.md). + +6. Create the vertex buffer passing in the **typeof(CustomVertex1)** instead of a vertex declaration to describe the vertex buffer data. + + ```csharp + vertexBuffer = new VertexBuffer( + graphics.GraphicsDevice, + typeof(CustomVertex1), + number_of_vertices, + BufferUsage.None + ); + ``` + +7. Create the per-vertex data; this shows a portion of the code. + + ```csharp + Vector3 LeftTopFront = new Vector3(-1.0f, 1.0f, 1.0f); + Vector3 LeftBottomFront = new Vector3(-1.0f, -1.0f, 1.0f); + Vector3 LeftTopBack = new Vector3(-1.0f, 1.0f, -1.0f); + Vector3 LeftBottomBack = new Vector3(-1.0f, -1.0f, -1.0f); + + Vector3 RightTopFront = new Vector3(1.0f, 1.0f, 1.0f); + Vector3 RightBottomFront = new Vector3(1.0f, -1.0f, 1.0f); + Vector3 RightTopBack = new Vector3(1.0f, 1.0f, -1.0f); + Vector3 RightBottomBack = new Vector3(1.0f, -1.0f, -1.0f); + + Vector2 textureLeftTop = new Vector2(0.0f, 0.0f); + Vector2 textureLeftBottom = new Vector2(0.0f, 1.0f); + Vector2 textureRightTop = new Vector2(1.0f, 0.0f); + Vector2 textureRightBottom = new Vector2(1.0f, 1.0f); + + // Front face. + cubeVertices[0] = new CustomVertex1(LeftTopFront, textureLeftTop); + cubeVertices[1] = new CustomVertex1(LeftBottomFront, textureLeftBottom); + cubeVertices[2] = new CustomVertex1(RightTopFront, textureRightTop); + cubeVertices[3] = new CustomVertex1(LeftBottomFront, textureLeftBottom); + cubeVertices[4] = new CustomVertex1(RightBottomFront, textureRightBottom); + cubeVertices[5] = new CustomVertex1(RightTopFront, textureRightTop); + ``` + + > For a triangle list, you need three vertices for a triangle and two triangles to make the front face of a cube. + +8. Set the data into the vertex buffer data by calling [VertexBuffer.SetData](xref:Microsoft.Xna.Framework.Graphics.VertexBuffer) and set the vertex buffer to the device by calling [GraphicsDevice.SetVertexBuffer](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice). + + ```csharp + vertexBuffer.SetData(cubeVertices); + + graphics.GraphicsDevice.SetVertexBuffer(vertexBuffer); + ``` + +9. Draw the object by calling [GraphicsDevice.DrawPrimitives](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice). + + ```csharp + RasterizerState rasterizerState1 = new RasterizerState(); + rasterizerState1.CullMode = CullMode.None; + graphics.GraphicsDevice.RasterizerState = rasterizerState1; + + foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) + { + pass.Apply(); + + graphics.GraphicsDevice.DrawPrimitives( + PrimitiveType.TriangleList, + 0, // start vertex + 12 // number of primitives to draw + ); + } + ``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/HowTo_UseViewportForSplitscreenGaming.md b/articles/monogame/howto/graphics/HowTo_UseViewportForSplitscreenGaming.md new file mode 100644 index 0000000..8c359e9 --- /dev/null +++ b/articles/monogame/howto/graphics/HowTo_UseViewportForSplitscreenGaming.md @@ -0,0 +1,93 @@ +--- +title: How to display Multiple Screens with Viewports +description: Demonstrates how to use viewports to display different scenes simultaneously using two cameras. +--- + +# Displaying Multiple Screens with Viewports + +Demonstrates how to use viewports to display different scenes simultaneously using two cameras. + +![A Split screen Example](../images/graphics_split_screen.png) + +## To create multiple screens + +1. In your [LoadContent](xref:Microsoft.Xna.Framework.Game) method, create two new [Viewport](xref:Microsoft.Xna.Framework.Graphics.Viewport) objects to define the two new "split" regions of the screen. + + > In this example, the screen is split in half vertically. + + ```csharp + Viewport defaultViewport; + Viewport leftViewport; + Viewport rightViewport; + Matrix projectionMatrix; + Matrix halfprojectionMatrix; + + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + defaultViewport = GraphicsDevice.Viewport; + leftViewport = defaultViewport; + rightViewport = defaultViewport; + leftViewport.Width = leftViewport.Width / 2; + rightViewport.Width = rightViewport.Width / 2; + rightViewport.X = leftViewport.Width; + ``` + +2. Create a projection matrix to fit each new viewport. + + In this case, because the screen is split in half, only one new projection matrix is necessary. It has the same settings as the 4:3 full screen projection matrix, except the aspect ratio is now 2:3. + + ```csharp + projectionMatrix = Matrix.CreatePerspectiveFieldOfView( + MathHelper.PiOver4, 4.0f / 3.0f, 1.0f, 10000f); + + halfprojectionMatrix = Matrix.CreatePerspectiveFieldOfView( + MathHelper.PiOver4, 2.0f / 3.0f, 1.0f, 10000f); + } + ``` + +3. In your Game [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method, assign one of the viewports to draw as the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice)[Viewport](xref:Microsoft.Xna.Framework.Graphics.Viewport). + +4. Draw your scene as normal, using the camera (or view matrix) associated with this perspective along with the proper projection matrix. + + ```csharp + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Viewport = defaultViewport; + GraphicsDevice.Clear(Color.CornflowerBlue); + + GraphicsDevice.Viewport = leftViewport; + DrawScene(gameTime, Camera1.ViewMatrix, halfprojectionMatrix); + ``` + +5. After drawing the first scene, assign the other viewport to the [Viewport](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Viewport) property. + +6. Draw your scene again with the associated camera or view matrix, and the proper projection matrix. + + ```csharp + GraphicsDevice.Viewport = rightViewport; + DrawScene(gameTime, Camera2.ViewMatrix, halfprojectionMatrix); + + base.Draw(gameTime); + + } + ``` + +## See Also + +### Concepts + +[What Is a Viewport?](../../whatis/graphics/WhatIs_Viewport.md) + +#### Reference + +[GraphicsDevice.Viewport](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) +[Viewport Structure](xref:Microsoft.Xna.Framework.Graphics.Viewport) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/index.md b/articles/monogame/howto/graphics/index.md new file mode 100644 index 0000000..39da0a0 --- /dev/null +++ b/articles/monogame/howto/graphics/index.md @@ -0,0 +1,159 @@ +--- +title: How to +description: A series of articles on how to do certain tasks in MonoGame! +--- + +# "How To" Articles for MonoGame + +These articles provide a details on how to use the Graphics API in MonoGame. + +## In This Section + +This section demonstrates several graphical concepts divided into three categories: + +* [2D Sprite Rendering](#2d-sprite-rendering) +* [Cameras](#cameras) +* [3D Rendering](#3d-rendering) +* [3D Collisions](#3d-collisions) + +### 2D Sprite Rendering + +This section walks through several core concepts related to sprite rendering, including drawing text to the screen. + +[How To Animate A Sprite](HowTo_Animate_Sprite.md) + +Demonstrates how to animate a sprite from a texture using a custom class. + +[How To Draw A Sprite](HowTo_Draw_A_Sprite.md) + +Demonstrates how to draw a sprite by using the SpriteBatch class. + +[How To Draw A Sprite Background](HowTo_Draw_Sprite_Background.md) + +Demonstrates how to draw a foreground and background sprite using the SpriteBatch class, where only part of the foreground sprite masks the background. + +[How To Draw A Sprite Over A Model](HowTo_Draw_Sprite_Over_Model.md) + +Demonstrates how to draw a sprite so that it obscures a model. In this example, we are drawing an animated sprite representing an explosion over the current screen position of a 3D model. + +[How To Draw Text](HowTo_Draw_Text.md) + +Demonstrates how to import a SpriteFont into a project and to draw text using the DrawString method. + +[How To Make A Scrolling Background](HowTo_Make_Scrolling_Background.md) + +Demonstrates how to draw a scrolling background sprite using the SpriteBatch class. + +[How To Rotate A Sprite](HowTo_Rotate_Sprite.md) + +Demonstrates how to rotate a sprite around its center. + +[How To Rotate A Sprite Group](HowTo_Rotate_Sprite_Group.md) + +Demonstrates how to rotate a group of sprites around a single point. + +[How To Scale A Sprite](HowTo_Scale_Sprite.md) + +Demonstrates how to scale a sprite using a uniform scale. + +[How To Scale A Sprite using A Matrix](HowTo_Scale_Sprites_Matrix.md) + +Demonstrates how to scale sprites using a matrix that is created based on the viewport width. + +[How To Tile Sprites](HowTo_Tile_Sprites.md) + +Demonstrates how to draw a sprite repeatedly in the x and y directions in one Draw call. + +[How To Tint A Sprite](HowTo_Tint_Sprite.md) + +Demonstrates how to tint a sprite using a Color value. + +### Cameras + +This section walks through several core concepts related to camera operations with MonoGame, including working with multiple screens/viewports. + +[How to position the Camera](HowTo_FitCameraToScene.md) + +Demonstrates how to position the camera so that all objects in a scene are within the view frustum while maintaining the camera's original orientation. + +[How to create a Full-Screen Game](HowTo_FullScreen.md) + +Demonstrates how to start a game in full-screen mode. + +[How to restrict Aspect Ratio on a Graphics Device](HowTo_AspectRatio.md) + +Demonstrates how to create a custom GraphicsDeviceManager that only selects graphics devices with widescreen aspect ratios in full-screen mode. + +[How to create a Render Target](HowTo_Create_a_RenderTarget.md) + +Demonstrates how to create a render target using the RenderTarget2D class. + +[How to display Multiple Screens with Viewports](HowTo_UseViewportForSplitscreenGaming.md) + +Demonstrates how to use viewports to display different scenes simultaneously using two cameras. + +[Rotating and Moving the Camera](HowTo_RotateMoveCamera.md) + +Demonstrates how to rotate and move a camera in a 3D environment. You can rotate the camera about its y-axis, and move it forward and backward. You control the camera's position and orientation by using the directional keys on your keyboard or by using the D-pad of your gamepad. + +[How to move the Camera on a Curve](HowTo_ScriptedCamera.md) + +Demonstrates how to use the Curve and CurveKey classes to move a camera along the shape of a curve. + +### 3D Rendering + +This section walks through several core concepts related 3D rendering and math practices with MonoGame. + +[How to transform a Point](HowTo_TransformPoint.md) + +This example demonstrates how to use the Vector3 and Matrix classes to transform a point. A matrix transform can include scaling, rotating, and translating information. + +[How to create a Basic Effect](HowTo_Create_a_BasicEffect.md) + +Demonstrates how to create and initialize an instance of the BasicEffect class and use it to draw simple geometry. + +[Using a Basic Effect with Texturing](HowTo_Draw_Textured_Quad.md) + +Demonstrates how to create and draw a simple quad—two triangles that form a rectangle or square—using **DrawUserIndexedPrimitives**. + +[How to render a Model using a Basic Effect](HowTo_RenderModel.md) + +Demonstrates how to load and render a model using the MonoGame Content Pipeline. It is assumed that an existing Windows game project is loaded in MonoGame. + +[How to enable Anti-aliasing](HowTo_Enable_Anti_Aliasing.md) + +Demonstrates how to enable anti-aliasing for your game. + +[How to create a State Object](HowTo_Create_a_StateObject.md) + +Demonstrates how to create a state object using any of the state object classes: BlendState, DepthStencilState, RasterizerState, or SamplerState. + +[How to create a Custom Vertex Declaration](HowTo_UseACustomVertex.md) + +Demonstrates how to create a custom vertex declaration and use it to render a 3D object. + +[How to Dynamically Update Vertex Data](HowTo_DynamicallyUpdateVertices.md) + +Geometry in a 3D game is defined by vertex data. Sometimes, a game needs to modify vertex data or even generate new vertex data dynamically (at run time). Here are some solutions for dynamically updating vertex data. + +[Drawing 3D Primitives using Lists or Strips](HowTo_Draw_3D_Primitives.md) + +Demonstrates how to draw 3D primitives using lines and triangles arranged as strips or lists. + +### 3D Collisions + +[Bounding Volumes and Collisions](../HowTo_CollisionDetectionOverview.md) + +Collision detection determines whether objects in a game world overlap each other. + +[Selecting an Object with a Mouse](HowTo_Select_and_Object_with_a_Mouse.md) + +Demonstrates how to check whether the mouse is positioned over a 3D object by creating a ray starting at the camera's near clipping plane and ending at its far clipping plane. + +[Testing for Collisions](HowTo_Test_for_Collisions.md) + +Demonstrates how to use the BoundingSphere class to check whether two models are colliding. + +--- + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/graphics/toc.yml b/articles/monogame/howto/graphics/toc.yml new file mode 100644 index 0000000..799b888 --- /dev/null +++ b/articles/monogame/howto/graphics/toc.yml @@ -0,0 +1,4 @@ +- name: Introduction + href: index.md +- name: How To Draw a Sprite + href: HowTo_Draw_A_Sprite.md diff --git a/articles/monogame/howto/images/CP_HowTo_Localize_Strings.png b/articles/monogame/howto/images/CP_HowTo_Localize_Strings.png new file mode 100644 index 0000000..88d0fb8 Binary files /dev/null and b/articles/monogame/howto/images/CP_HowTo_Localize_Strings.png differ diff --git a/articles/monogame/howto/images/CP_HowTo_Localize_Strings_fr.png b/articles/monogame/howto/images/CP_HowTo_Localize_Strings_fr.png new file mode 100644 index 0000000..8440d0b Binary files /dev/null and b/articles/monogame/howto/images/CP_HowTo_Localize_Strings_fr.png differ diff --git a/articles/monogame/howto/images/CP_HowTo_Localize_Strings_ja.png b/articles/monogame/howto/images/CP_HowTo_Localize_Strings_ja.png new file mode 100644 index 0000000..5d9b63a Binary files /dev/null and b/articles/monogame/howto/images/CP_HowTo_Localize_Strings_ja.png differ diff --git a/articles/monogame/howto/images/HowTo_Create_a_RenderTarget_Final.png b/articles/monogame/howto/images/HowTo_Create_a_RenderTarget_Final.png new file mode 100644 index 0000000..7684b4c Binary files /dev/null and b/articles/monogame/howto/images/HowTo_Create_a_RenderTarget_Final.png differ diff --git a/articles/monogame/howto/images/HowTo_Load_XML_Final.png b/articles/monogame/howto/images/HowTo_Load_XML_Final.png new file mode 100644 index 0000000..dcaf0a3 Binary files /dev/null and b/articles/monogame/howto/images/HowTo_Load_XML_Final.png differ diff --git a/articles/monogame/howto/images/graphics_aa.jpg b/articles/monogame/howto/images/graphics_aa.jpg new file mode 100644 index 0000000..a29ea75 Binary files /dev/null and b/articles/monogame/howto/images/graphics_aa.jpg differ diff --git a/articles/monogame/howto/images/graphics_custom_vertex.png b/articles/monogame/howto/images/graphics_custom_vertex.png new file mode 100644 index 0000000..8073eb0 Binary files /dev/null and b/articles/monogame/howto/images/graphics_custom_vertex.png differ diff --git a/articles/monogame/howto/images/graphics_split_screen.png b/articles/monogame/howto/images/graphics_split_screen.png new file mode 100644 index 0000000..d80315c Binary files /dev/null and b/articles/monogame/howto/images/graphics_split_screen.png differ diff --git a/articles/monogame/howto/images/graphics_sprite_tiled.jpg b/articles/monogame/howto/images/graphics_sprite_tiled.jpg new file mode 100644 index 0000000..da4c5b2 Binary files /dev/null and b/articles/monogame/howto/images/graphics_sprite_tiled.jpg differ diff --git a/articles/monogame/howto/images/grid.png b/articles/monogame/howto/images/grid.png new file mode 100644 index 0000000..e41ac4a Binary files /dev/null and b/articles/monogame/howto/images/grid.png differ diff --git a/articles/monogame/howto/index.md b/articles/monogame/howto/index.md new file mode 100644 index 0000000..ef588cc --- /dev/null +++ b/articles/monogame/howto/index.md @@ -0,0 +1,71 @@ +--- +title: How To +description: A series of articles to answer common questions related to MonoGame operation! +--- + +# "How To" Articles for MonoGame + +These articles provide a brief introduction into performing some basic tasks in MonoGame. + +## In This Section + +The section is broken down into 4 distinct categories: + +* [Core concepts](#core-concepts) +* [Game Operations](#game-operations) +* [Guidance](#guidance) + +### Core concepts + +This section details the core concepts to understand how MonoGame projects fit together. + +[Audio](./audio/index.md) +[graphics](./graphics/index.md) +[content pipeline](./content_pipeline/index.md) +[Input](./input/index.md) + +### Game Operations + +This section details some of the operational aspects of running a MonoGame game. + +[How to manage automatic rotation and scaling](HowTo_AutomaticRotation.md) + +A walkthrough what is involved in figuring out if two objects collide for MonoGame! + +[How to exit a Game Immediately](HowTo_ExitNow.md) + +Demonstrates how to exit a game in response to user input. + +[How to exit a Game After a Time Out](HowTo_TimingOut.md) + +Demonstrates how to exit a game after a period of time (such as inactivity) has passed. + +[How to update a game with Variable or Fixed Timing](HowTo_VariableStepGameLoop.md) + +Demonstrates how to set up the runtime to call your Update method using variable or fixed timing. + +[How to Save and Load data using MonoGame](HowTo_SaveData.md) + +Demonstrates reading and writing data in MonoGame projects. + +[How to handle resizing of a Game](HowTo_PlayerResize.md) + +Demonstrates how to handle the resizing of the active game window. + +### Guidance + +This section contains articles to help make your MonoGame project successful. + +[How to work with Asynchronous Methods in MonoGame](HowTo_AsyncProgramming.md) + +This topic describes how you can work with asynchronous methods in MonoGame. + +[How to apply Best Practices for MonoGame Games](HowTo_MobileBestPractices.md) + +The practices discussed here will help you have the most success possible with your MonoGame game. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/HowTo_DetectClicked3DObject.md b/articles/monogame/howto/input/HowTo_DetectClicked3DObject.md new file mode 100644 index 0000000..4dbbcbc --- /dev/null +++ b/articles/monogame/howto/input/HowTo_DetectClicked3DObject.md @@ -0,0 +1,80 @@ +--- +title: How to select an Object in 3D Space +description: Demonstrates how to check whether the mouse (or touch location) is positioned over a 3D object by creating a ray starting at the camera's near clipping plane and ending at its far clipping plane. +--- + +# Selecting an Object in 3D Space + +Demonstrates how to check whether the mouse (or touch location) is positioned over a 3D object by creating a ray starting at the camera's near clipping plane and ending at its far clipping plane. + +> [!TIP] +> This example applies most directly to Windows development where mice are ubiquitous and Mobile where a touch replaces a mouse. + +Because the [Mouse](xref:Microsoft.Xna.Framework.Input.Mouse) class and [MouseState](xref:Microsoft.Xna.Framework.Input.MouseState) structure do provide limited functionality on Windows Phone, this sample should work, as is, on that platform as well. However, a better solution on Windows Phone would be to substitute a call to the [TouchPanel.GetState](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetState) method for the call to the [Mouse.GetState](xref:Microsoft.Xna.Framework.Input.Mouse.GetState) method in order to retrieve alternative X and Y coordinates from a Windows Phone touch screen. In general, games and other applications designed for Windows Phone should use the [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) class to retrieve user input. + +As written, this sample is least applicable to consoles, although the technique of creating a ray and then keeping track of the closest object that intersects the ray remains potentially useful. + +## Detecting Whether a User Clicked a 3D Object + +> If you replace **Mouse** with **Touch**, you can apply this method to Mobiles too. + +### To check whether the mouse is positioned over a 3D object + +1. Get the current state of the mouse by using [GetState](xref:Microsoft.Xna.Framework.Input.Mouse.GetState). + + ```csharp + MouseState mouseState = Mouse.GetState(); + ``` + +2. Get the current screen coordinates of the mouse from [X](xref:Microsoft.Xna.Framework.Input.MouseState.X) and [Y](xref:Microsoft.Xna.Framework.Input.MouseState.Y). + + ```csharp + int mouseX = mouseState.X; + int mouseY = mouseState.Y; + ``` + +3. Using [Viewport.Unproject](xref:Microsoft.Xna.Framework.Graphics.Viewport), determine points in world space on the near and far clipping planes. For the point on the near plane, pass a source vector with x and y set to the mouse position, and z set to 0. + +4. For the point on the far plane, pass a source vector with x and y set to the mouse position, and z set to 1. + +5. Create a translation matrix for a point that is the origin, (0,0,0). + +6. For both points, pass [Unproject](xref:Microsoft.Xna.Framework.Graphics.Viewport) the current projection matrix, the view matrix. + + ```csharp + Vector3 nearsource = new Vector3((float)mouseX, (float)mouseY, 0f); + Vector3 farsource = new Vector3((float)mouseX, (float)mouseY, 1f); + + Matrix world = Matrix.CreateTranslation(0, 0, 0); + + Vector3 nearPoint = GraphicsDevice.Viewport.Unproject(nearsource, + proj, view, world); + + Vector3 farPoint = GraphicsDevice.Viewport.Unproject(farsource, + proj, view, world); + ``` + +7. Create a [Ray](xref:Microsoft.Xna.Framework.Ray) whose origin is at the near point and whose direction points to the far point. + + ```csharp + // Create a ray from the near clip plane to the far clip plane. + Vector3 direction = farPoint - nearPoint; + direction.Normalize(); + Ray pickRay = new Ray(nearPoint, direction); + ``` + +8. Loop through each object in the scene using the **Intersects** method to check whether the [Ray](xref:Microsoft.Xna.Framework.Ray) intersects each object. + +9. If the [Ray](xref:Microsoft.Xna.Framework.Ray) intersects an object, check whether it is the closest object intersected so far. If it is, store the object and the distance at which it was intersected, replacing any previously stored object. + +10. When you completely loop through the objects, the last object stored will be the closest object underneath the area the user clicked. + +## See Also + +[Rotating and Moving the Camera](../graphics/HowTo_RotateMoveCamera.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/HowTo_DetectGamePadInput.md b/articles/monogame/howto/input/HowTo_DetectGamePadInput.md new file mode 100644 index 0000000..45cc447 --- /dev/null +++ b/articles/monogame/howto/input/HowTo_DetectGamePadInput.md @@ -0,0 +1,121 @@ +--- +title: Detecting input from a GamePad +description: The code in this topic describes how to detect input on a GamePad. +--- + +# Detecting input from a GamePad + +By using [GamePad.GetState](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_GetState_System_Int32_) a game can determine which buttons are being held down. A game often needs to detect when a user has pressed or released a button. For example, there is the case of an action title that requires users to press and release keys in rapid succession. The example uses a cached [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState) object to determine if buttons were pressed or released in a given frame. + +Unlike GamePads however, multiple GamePads can be connected to a computer or console at the same time, so the [GamePad.GetState](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_GetState_System_Int32_) call requires an Index parameter for which controller is being polled. You also need to query the system the game is currently on for its [GamePad.MaximumGamePadCount](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_MaximumGamePadCount) to determine how many controllers are supported and how many need to be polled for each frame. Also unlike GamePads, GamePads can be disconnected (especially if the battery dies) at any time and most consoles require you to validate this to avoid player issues. + +Depending on game design, there may be times when checking for a button press needs to occur more frequently, and other times it does not. It is possible in the case of very fast button presses that more than one key press could occur within one frame. In such a case, the last button press is returned. Writing code that checks as often as possible for button presses is the best way to handle this case. + +## Types of GamePad input + +Most GamePads include a variety of different input options, including (but not limited to) + +* Thumbsticks - providing ranged motion in two axis. +* Buttons (including buttons on the Thumbsticks) - Digital on/off buttons (similar to keyboard keys) +* Triggers - providing ranged motion in a singular axis. +* Touchpads - in some advanced controllers (such as the PlayStation Dual Shock controller) include a small touchpad. + +Additionally, most controllers also support haptic feedback (vibration) in the controller, which is different depending on the controller being used and for which system. + +> Joysticks also work the same as GamePads, but use their own [Joystick](xref:Microsoft.Xna.Framework.Input.Joystick) and [JoystickState](xref:Microsoft.Xna.Framework.Input.JoystickState) classes. Operationally however, they work the same as GamePads. + +## Detecting input changes on a GamePad + +1. Declare a [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState) object to hold the last known GamePad state (in this example, the **oldState** object). + +2. Assign this object a value in your constructor. + +3. Call [GamePad.GetState](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_GetState_System_Int32_) to retrieve the current GamePad state (in this example, the **newState** object). + +4. Compare the values in your **newState** object to the values in the **oldState** object. + + Buttons pressed in the **newState** object that were not pressed in the **oldState** object were pressed during this frame. Conversely, buttons pressed in the **oldState** object that are not pressed in the **newState** object were released during this frame. + + > For Thumbsticks and Triggers, it is not necessary to compare to the previous value unless you also need to calculate the difference, e.g. Was the variable controller moved fast or slow. Reading just the current value is usually enough. + +5. Update **oldState** object to the **newState** object before leaving **Update**. + +```csharp +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace GamePadInput +{ + public class Game1 : Microsoft.Xna.Framework.Game + { + GraphicsDeviceManager graphics; + GamePadState oldState; + + public Game1() + { + graphics = new GraphicsDeviceManager(this); + } + + protected override void Initialize() + { + base.Initialize(); + oldState = GamePad.GetState(PlayerIndex.One); + } + + protected override void Update(GameTime gameTime) + { + // Allows the game to exit + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) + { + this.Exit(); + } + + UpdateInput(); + + base.Update(gameTime); + } + + private void UpdateInput() + { + GamePadState newState = GamePad.GetState(PlayerIndex.One); + + // Is the A Button down? + if (newState.IsButtonDown(Buttons.A)) + { + if (!oldState.IsButtonDown(Buttons.A)) + { + // If not down last update, the button has just been pressed. + } + } + else if (oldState.IsButtonDown(Buttons.A)) + { + // Button was down last update, but not down now, so it has just been released. + } + + // Which direction is the right thumbstick being moved? + Vector2 direction = newState.ThumbSticks.Right; + + // How much is the left trigger being squeezed? + float leftTriggerAmount = newState.Triggers.Left; + + // Update saved state. + oldState = newState; + } + + protected override void Draw(GameTime gameTime) + { + base.Draw(gameTime); + } + } +} +``` + +The above sample demonstrates sampling just the first connected controller, to support multiple controllers, you will need to sample from all connected controllers (as well as managing their connected state in case one is disconnected) and use an array of [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState) to maintain the cache of all controllers. + +> P.S. Most mobiles these days can support Bluetooth GamePads, so make sure you also support them if you intend to ship your game on mobile. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/HowTo_DetectKeyPress.md b/articles/monogame/howto/input/HowTo_DetectKeyPress.md new file mode 100644 index 0000000..f8ddf74 --- /dev/null +++ b/articles/monogame/howto/input/HowTo_DetectKeyPress.md @@ -0,0 +1,94 @@ +--- +title: Detecting a Key Press +description: The code in this topic describes how to detect a key press or release on the keyboard. +--- + +# Detecting a Key Press + +By using [GetState](xref:Microsoft.Xna.Framework.Input.Keyboard.GetState) a game can determine which keys are being held down. A game often needs to detect when a user has pressed or released a key. For example, there is the case of an action title that requires users to press and release keys in rapid succession. The example uses a cached [KeyboardState](xref:Microsoft.Xna.Framework.Input.KeyboardState) object to determine if keys were pressed or released in a given frame. + +Depending on game design, there may be times when checking for a key press needs to occur more frequently, and other times it does not. It is possible in the case of very fast key presses that more than one key press could occur within one frame. In such a case, the last key press is returned. Writing code that checks as often as possible for key presses is the best way to handle this case. + +## Detecting a Key Press or Release + +1. Declare a [KeyboardState](xref:Microsoft.Xna.Framework.Input.KeyboardState) object to hold the last known keyboard state (in this example, the **oldState** object). + +2. Assign this object a value in your constructor. + +3. Call [GetState](xref:Microsoft.Xna.Framework.Input.Keyboard.GetState) to retrieve the current keyboard state (in this example, the **newState** object). + +4. Compare the values in your **newState** object to the values in the **oldState** object. + + Keys pressed in the **newState** object that were not pressed in the **oldState** object were pressed during this frame. Conversely, keys pressed in the **oldState** object that are not pressed in the **newState** object were released during this frame. + +5. Update **oldState** object to the **newState** object before leaving **Update**. + +```csharp +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace Keypress +{ + public class Game1 : Microsoft.Xna.Framework.Game + { + GraphicsDeviceManager graphics; + KeyboardState oldState; + + public Game1() + { + graphics = new GraphicsDeviceManager(this); + } + + protected override void Initialize() + { + base.Initialize(); + oldState = Keyboard.GetState(); + } + + protected override void Update(GameTime gameTime) + { + // Allows the game to exit + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) + { + this.Exit(); + } + + UpdateInput(); + + base.Update(gameTime); + } + + private void UpdateInput() + { + KeyboardState newState = Keyboard.GetState(); + + // Is the SPACE key down? + if (newState.IsKeyDown(Keys.Space)) + { + if (!oldState.IsKeyDown(Keys.Space)) + { + // If not down last update, key has just been pressed. + } + } + else if (oldState.IsKeyDown(Keys.Space)) + { + // Key was down last update, but not down now, so it has just been released. + } + + // Update saved state. + oldState = newState; + } + + protected override void Draw(GameTime gameTime) + { + base.Draw(gameTime); + } + } +} +``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/HowTo_Detect_Gestures.md b/articles/monogame/howto/input/HowTo_Detect_Gestures.md new file mode 100644 index 0000000..6cb48fb --- /dev/null +++ b/articles/monogame/howto/input/HowTo_Detect_Gestures.md @@ -0,0 +1,77 @@ +--- +title: Detecting Gestures on a multi-touch Screen +description: This topic demonstrates how to detect and use multi-touch gestures in a MonoGame game. +--- + +# Detecting Gestures on a multi-touch Screen + +The code in this topic shows you the technique for detecting and using multi-touch gestures. You can download a complete code sample for this topic, including full source code and any additional supporting files required by the sample. + +MonoGame supports multi-touch gesture-based input on Mobile. The primary class that provides this support is [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel), which provides the ability to: + +* Designate which gestures should be detected. +* Query to see if any gestures are available for processing. + +> Gesture support is provided as a convenient subset of the features possible on a multi-touch input device. For more information about general multi-touch programming, see [Working with Touch Input](HowTo_UsemultitouchInput.md). + +## How to detect Gestures on a multi-touch Screen + +1. Set the gestures to enable with [TouchPanel.EnabledGestures](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel). This can be one value, or a combination of values, in the [GestureType](xref:Microsoft.Xna.Framework.Input.Touch) enumeration. Performance can be decreased by enabling all gestures, so it is a good practice to enable only the gestures you'll be using in your game. + +2. During your game loop, check to see if any gestures are available with [TouchPanel.IsGestureAvailable](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.IsGestureAvailable). When [IsGestureAvailable](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.IsGestureAvailable) is **false**, there are no more gestures in the queue. + +3. If gestures are available, call [TouchPanel.ReadGesture](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) to get a [GestureSample](xref:Microsoft.Xna.Framework.Input.Touch) that contains the data for the gesture. + +> Some gestures will be preceded by another gesture that begins the gesture. For instance, a **DoubleTap** gesture is always preceded by a **Tap** gesture. For more information about the various gesture types supported, see [GestureType](xref:Microsoft.Xna.Framework.Input.Touch). + +## Example + +The following code illustrates the procedure for detecting gestures on a multi-touch screen. + +* Enabling gestures in the game's constructor: + + ```csharp + // set up touch gesture support: make vertical drag and flick the + // gestures that we're interested in. + TouchPanel.EnabledGestures = + GestureType.VerticalDrag | GestureType.Flick; + ``` + +* Detecting gestures in the game's Update method: + + ```csharp + // get any gestures that are ready. + while (TouchPanel.IsGestureAvailable) + { + GestureSample gs = TouchPanel.ReadGesture(); + switch (gs.GestureType) + { + case GestureType.VerticalDrag: + // move the poem screen vertically by the drag delta + // amount. + poem.offset.Y -= gs.Delta.Y; + break; + + case GestureType.Flick: + // add velocity to the poem screen (only interested in + // changes to Y velocity). + poem.velocity.Y += gs.Delta.Y; + break; + } + } + ``` + +## See Also + +### Reference + +[Microsoft.Xna.Framework.Input.Touch](xref:Microsoft.Xna.Framework.Input.Touch) +[TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) +[GestureType](xref:Microsoft.Xna.Framework.Input.Touch.GestureType) +[GestureSample](xref:Microsoft.Xna.Framework.Input.Touch.GestureSample) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/HowTo_UseMultiTouchInput.md b/articles/monogame/howto/input/HowTo_UseMultiTouchInput.md new file mode 100644 index 0000000..beb3020 --- /dev/null +++ b/articles/monogame/howto/input/HowTo_UseMultiTouchInput.md @@ -0,0 +1,81 @@ +--- +title: How to work with Touch Input +description: This topic demonstrates how to detect and use multi-touch input in a MonoGame game. +--- + +# Working with Touch Input + +MonoGame supports multi-touch input on Mobile. The primary class that provides this support is [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel), which can: + +* Determine the touch capabilities of the current device. +* Get the current state of the touch panel. +* Detect touch gestures such as flicks, pinches, and drags. (For more information, see [Detecting Gestures on a multi-touch Screen](HowTo_Detect_Gestures.md).) + +## Determining the Capabilities of the Touch Input Device + +By using [TouchPanel.GetCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetCapabilities) you can determine if the touch panel is available. You also can determine the maximum touch count (the number of touches that can be detected simultaneously). + +## To determine the capabilities of the touch device + +1. Call [TouchPanel.GetCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel), which returns a [TouchPanelCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) structure. + +2. Ensure [TouchPanelCapabilities.IsConnected](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) is **true**, indicating that the touch panel is available for reading. + +3. You then can use the [TouchPanelCapabilities.MaximumTouchCount](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) property to determine how many touch points are supported by the touch panel. + +> All touch panels for mobile return a [MaximumTouchCount](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) value of 4 in MonoGame. + +The following code demonstrates how to determine if the touch panel is connected, and then reads the maximum touch count. + + ```csharp + TouchPanelCapabilities tc = TouchPanel.GetCapabilities(); + if(tc.IsConnected) + { + return tc.MaximumTouchCount; + } + ``` + +## Getting multi-touch Data from the Touch Input Device + +You can use [TouchPanel.GetState](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) to get the current state of the touch input device. It returns a [TouchCollection](xref:Microsoft.Xna.Framework.Input.Touch.TouchCollection) structure that contains a set of [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation) structures, each containing information about position and state for a single touch point on the screen. + +## To read multi-touch data from the touch input device + +1. Call [TouchPanel.GetState](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) to get a [TouchCollection](xref:Microsoft.Xna.Framework.Input.Touch.TouchCollection) representing the current state of the device. + +2. For each [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation) in the [TouchCollection](xref:Microsoft.Xna.Framework.Input.Touch.TouchCollection), read the location and state data provided for each touch point. + +The following code demonstrates how to get the current state of the touch input device and read touch data from each [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation). It checks to see if a touch location has been pressed or has moved since the last frame, and if so, draws a sprite at the touch location. + + ```csharp + // Process touch events + TouchCollection touchCollection = TouchPanel.GetState(); + foreach (TouchLocation tl in touchCollection) + { + if ((tl.State == TouchLocationState.Pressed) + || (tl.State == TouchLocationState.Moved)) + { + + // add sparkles based on the touch location + sparkles.Add(new Sparkle(tl.Position.X, + tl.Position.Y, ttms)); + + } + } + ``` + +## See Also + +### Reference + +[Microsoft.Xna.Framework.Input.Touch](xref:Microsoft.Xna.Framework.Input.Touch) +[TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) +[TouchPanelCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) +[TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation) +[TouchLocationState](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocationState) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/index.md b/articles/monogame/howto/input/index.md new file mode 100644 index 0000000..44191e8 --- /dev/null +++ b/articles/monogame/howto/input/index.md @@ -0,0 +1,40 @@ +--- +title: Working with Input +description: This section provides topics that demonstrate how to write code that managed input in your MonoGame project for keyboard, mouse, gamepad and touch. +--- + +# Working with Input + +This section provides topics that demonstrate how to write code that managed input in your MonoGame project for keyboard, mouse, GamePad and touch. + +## In This Section + +[Overview of User Input and Input Devices](../../whatis/WhatIs_Input.md) + +Describes the various types of input devices that can be used with MonoGame. + +[Detecting a Key Press](HowTo_DetectKeyPress.md) + +Demonstrates how to detect if a user pressed or released a key on the keyboard. + +[Detecting a Button Press](HowTo_DetectGamePadInput.md) + +Demonstrates how to detect if a user performed input on a GamePad. + +[Working with Touch Input](HowTo_UseMultiTouchInput.md) + +Demonstrates how to detect and use multi-touch input in a MonoGame game. + +[Detecting Gestures on a Multi-touch Screen](HowTo_Detect_Gestures.md) + +Demonstrates how to detect and use multi-touch gestures in a MonoGame game. + +[How to select an Object in 3D Space](HowTo_DetectClicked3DObject.md) + +Demonstrates how to check whether the mouse (or touch location) is positioned over a 3D object by creating a ray starting at the camera's near clipping plane and ending at its far clipping plane. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/howto/input/toc.yml b/articles/monogame/howto/input/toc.yml new file mode 100644 index 0000000..4262931 --- /dev/null +++ b/articles/monogame/howto/input/toc.yml @@ -0,0 +1,2 @@ +- name: Introduction + href: index.md \ No newline at end of file diff --git a/articles/monogame/howto/toc.yml b/articles/monogame/howto/toc.yml new file mode 100644 index 0000000..2d98fe8 --- /dev/null +++ b/articles/monogame/howto/toc.yml @@ -0,0 +1,10 @@ +- name: Introduction + href: index.md +- name: Audio + href: audio/ +- name: Content Pipeline + href: content_pipeline/ +- name: Graphics + href: graphics/ +- name: Input + href: input/ \ No newline at end of file diff --git a/articles/monogame/index.md b/articles/monogame/index.md new file mode 100644 index 0000000..85ecb35 --- /dev/null +++ b/articles/monogame/index.md @@ -0,0 +1,28 @@ +--- +title: Documentation +description: Welcome to the MonoGame documentation hub! +--- + +# Welcome to the MonoGame documentation hub + +This new and improved documentation area aims to bridge the gaps in the understanding of the MonoGame Framework, covering all aspects of the features of MonoGame with some support from the original XNA documentation graciously donated by Microsoft. + +Please check back regularly for updates and more details on the evolution of the MonoGame Framework and its API. + +## In This Section + +[What Is articles](whatis/index.md) + +Provides simple definitions for most of the central concepts maintained by the MonoGame Framework. + +[How To articles](howto/index.md) + +Short guides for everything you wanted to know about how to do game development with MonoGame, divided up in to simple articles for each activity. + +## Online Resources + +[Check out the full API documentation here](/api/index.md) + +--- + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/toc.yml b/articles/monogame/toc.yml new file mode 100644 index 0000000..9e67aa2 --- /dev/null +++ b/articles/monogame/toc.yml @@ -0,0 +1,4 @@ +- name: What is + href: whatis/ +- name: How Tp + href: howto/ \ No newline at end of file diff --git a/articles/monogame/whatis/WhatIs_Audio.md b/articles/monogame/whatis/WhatIs_Audio.md new file mode 100644 index 0000000..8a111f4 --- /dev/null +++ b/articles/monogame/whatis/WhatIs_Audio.md @@ -0,0 +1,87 @@ +--- +title: Sounds Overview +description: An overview of how the MonoGame Framework provides audio playback through several core audio classes. +--- + +# Introduction + +If your game is to use a few sound files, then the [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect), [SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance), and [DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) classes will provide everything you need to play and stream audio during gameplay. + +## Simple Audio Playback + +The simplest way to play sounds for background music or sound effects is to use [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) and [SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance). Source audio files are added like any other game asset to the project. For example code, see [Playing a Sound](../HowTo/audio/HowTo_PlayASound.md), [Looping a Sound](../HowTo/audio/HowTo_LoopASound.md), and [Adjusting Pitch and Volume](../HowTo/audio/HowTo_ChangePitchAndVolume.md). For background music, see [Playing a Song](../HowTo/audio/HowTo_PlayASong.md). + +## Accessing the Audio Buffer + +Developers can use [DynamicSoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) for direct access to an audio buffer. By accessing the audio buffer, developers can manipulate sound, break up large sound files into smaller data chunks, and stream sound. For example code, see [Streaming Data from a WAV File](../HowTo/audio/HowTo_StreamDataFromWav.md). + +## 3D Audio + +The [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) class provides the ability to place audio in a 3D space. By creating [AudioEmitter](xref:Microsoft.Xna.Framework.Audio.AudioEmitter) and [AudioListener](xref:Microsoft.Xna.Framework.Audio.AudioListener) objects, the API can position a sound in 3D, and can change the 3D position of a sound during playback. Once you create and initialize [AudioEmitter](xref:Microsoft.Xna.Framework.Audio.AudioEmitter) and [AudioListener](xref:Microsoft.Xna.Framework.Audio.AudioListener), call [SoundEffectInstance.Apply3D](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance). + +## Audio Constraints + +When working with multiple platforms using MonoGame, there are a few constraints around audio that you will need to keep in mind and cater for, namely: + +* Mobile platforms have a maximum of 32 sounds playing simultaneously. +* Desktop platforms have a maximum of 256 sounds playing simultaneously. +* Consoles and other platforms have their own constraints, please look at the console sdk documentation for more information, + +An [InstancePlayLimitException](xref:Microsoft.Xna.Framework.Audio.InstancePlayLimitException) exception is thrown if this limit is exceeded. + +## Audio Buffer Format + +The byte\[\] buffer format used as a parameter for the [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) constructor, [Microphone.GetData](xref:Microsoft.Xna.Framework.Audio.Microphone) method, and [DynamicSoundEffectInstance.SubmitBuffer](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) method is PCM wave data. Additionally, the PCM format is interleaved and in little-endian. + +The audio format has the following constraints: + +* The audio channels can be mono (1) or stereo (2). +* The PCM wave file must have 16-bits per sample. +* The sample rate must be between 8,000 Hz and 48,000 Hz. +* The interleaving for stereo data is left channel to right channel. + +## Songs as Background Music + +Access to the media library, combined with the ability to use playlists, allows games to create interesting background scores that can change with gameplay. Songs can be played directly from the media library, or can be imported by using the Content Pipeline. For more information, see [Playing a Song](../howto/audio/HowTo_PlayASong.md). + +## Concepts + +[Playing a Sound](../howto/audio/HowTo_PlayASound.md) + +Demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). + +[Streaming Data from a WAV File](../howto/audio/HowTo_StreamDataFromWav.md) + +Demonstrates how to stream audio from a wave (.wav) file. + +[Playing a Song](../howto/audio/HowTo_PlayASong.md) + +Demonstrates how to play a song from a user's media library. + +[Playing a Song from a URI](../howto/audio/HowTo_PlaySongfromURI.md) + +Demonstrates how to use the [MediaPlayer](xref:Microsoft.Xna.Framework.Media.MediaPlayer) to play a song from a Uniform Resource Identifier (URI). + +## Reference + +[SoundEffect Class](xref:Microsoft.Xna.Framework.Audio.SoundEffect) + +Provides a loaded sound resource. + +[SoundEffectInstance Class](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) + +Provides a single playing, paused, or stopped instance of a [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) sound. + +[DynamicSoundEffectInstance Class](xref:Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance) + +Provides properties, methods, and events for play back of the audio buffer. + +[Song Class](xref:Microsoft.Xna.Framework.Media.Song) + +Provides access to a song in the song library. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/WhatIs_Input.md b/articles/monogame/whatis/WhatIs_Input.md new file mode 100644 index 0000000..475a8cc --- /dev/null +++ b/articles/monogame/whatis/WhatIs_Input.md @@ -0,0 +1,24 @@ +--- +title: Overview of User Input and Input Devices +description: Input is a general term referring to the process of receiving actions from the user. +--- + +# Overview of User Input and Input Devices + +Input is a general term referring to the process of receiving actions from the user. In MonoGame, the [Microsoft.Xna.Framework.Input](xref:Microsoft.Xna.Framework.Input) namespace provides support for most input devices. + +Methods related to input devices unavailable on the platform your game is running on are always available to your code. For example, you can access all [GamePad](xref:Microsoft.Xna.Framework.Input.GamePad) methods on Mobile, but they will not return valid information (unless a GamePad is connected). Although using these methods will not cause exceptions or build errors in your code, they will silently fail when run. + +Physical keyboards may or may not be present on mobile devices; you should not rely on the presence of a physical keyboard. For text input, you should use a software input panel (SIP), which will work on all devices, including those with physical keyboards. + +If the mobile device does have access to a physical keyboard, the same methods used for keyboards on desktop can be used, given a few caveats. + +For multi-touch devices, you can use the raw touch data provided by the [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) class, but you can also use MonoGame's support for predefined gestures if your input fits one of the supported gesture types. For information about working with raw multi-touch input, see [Working with Touch Input](../howto/input/HowTo_UseMultiTouchInput.md). For information about gesture support, see [Detecting Gestures on a Multi-touch Screen](../howto/input/HowTo_Detect_Gestures.md). + +The microphone on mobile can be used to capture audio that can be used in your game. For more information, see [Recording Sounds with Microphones](../howto/audio/HowTo_Microphone.md). + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/WhatIs_MonoGame_Class_Library.md b/articles/monogame/whatis/WhatIs_MonoGame_Class_Library.md new file mode 100644 index 0000000..2112af1 --- /dev/null +++ b/articles/monogame/whatis/WhatIs_MonoGame_Class_Library.md @@ -0,0 +1,60 @@ +--- +title: MonoGame Framework Class Library +description: MonoGame Framework Class Library Reference +--- + +# MonoGame Framework Class Library + +The MonoGame Framework class library is a library of classes, interfaces, and value types that are included in MonoGame Game Studio. This library provides access to MonoGame Framework functionality and is designed to be the foundation on which MonoGame Game Studio applications, components, and controls are built. + +## Namespaces + +- [Microsoft.Xna.Framework](xref:Microsoft.Xna.Framework) + + Provides commonly needed game classes such as timers and game loops. + +- [Microsoft.Xna.Framework.Audio](xref:Microsoft.Xna.Framework.Audio) + + Contains low-level application programming interface (API) methods that can load and manipulate content files to play audio. + +- [Microsoft.Xna.Framework.Content](xref:Microsoft.Xna.Framework.Content) + + Contains the run-time components of the Content Pipeline. + +- [Microsoft.Xna.Framework.Design](xref:Microsoft.Xna.Framework.Design) + + Provides a unified way of converting types of values to other types. + +- [Microsoft.Xna.Framework.Graphics](xref:Microsoft.Xna.Framework.Graphics) + + Contains low-level application programming interface (API) methods that take advantage of hardware acceleration capabilities to display 3D objects. + +- [Microsoft.Xna.Framework.Graphics.PackedVector](xref:Microsoft.Xna.Framework.Graphics.PackedVector) + + Represents data types with components that are not multiples of 8 bits. + +- [Microsoft.Xna.Framework.Input](xref:Microsoft.Xna.Framework.Input) + + Contains classes to receive input from keyboard, mouse, and GamePad devices. + +- [Microsoft.Xna.Framework.Input.Touch](xref:Microsoft.Xna.Framework.Input.Touch) + + Contains classes that enable access to touch-based input on devices that support it. + +- [Microsoft.Xna.Framework.Media](xref:Microsoft.Xna.Framework.Media) + + Contains classes to enumerate, play, and view songs, albums, playlists, and pictures. + +- Microsoft.Xna.Framework.Utilities + + Contains classes that provide additional support for working with MonoGame. + +- Microsoft.Xna.Framework.Utilities.Deflate + + Contains classes that provide additional support for compression with MonoGame. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/WhatIs_Profile.md b/articles/monogame/whatis/WhatIs_Profile.md new file mode 100644 index 0000000..66b4dff --- /dev/null +++ b/articles/monogame/whatis/WhatIs_Profile.md @@ -0,0 +1,80 @@ +--- +title: What Is a Profile? +description: The definition for a Graphics Profile for MonoGame! +--- + +# What Is a Profile? + +A profile is a feature set that is implemented in hardware. The Reach profile implements High Level Shader Language (HLSL) Shader Model 2.0 and the HiDef profile implements HLSL Shader Model 3.0. + +The Reach profile is the only profile available for mobile game development. Nevertheless, this topic provides background information about the purpose of MonoGame profiles and the differences between the Reach and HiDef profiles. + +To simplify multiplatform development, MonoGame creates a profile. A profile is platform independent so you do not need to query for capability bits. The APIs for accessing the features implemented in hardware are consistent across platforms so that game code written for one platform will compile and run on another platform with little or no changes. A game will not run if a hardware device does not meet the profile requirements. + +You can set the profile at design time by using the Monogame property page in Microsoft Visual Studio or you can set a profile at runtime by using the [GraphicsProfile](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.GraphicsProfile) property. For more information, see [Selecting Reach vs. HiDef](http://web.archive.org/web/20120102231201/http://blogs.msdn.com/b/shawnhar/archive/2010/07/19/selecting-reach-vs-hidef.aspx). + +There are two profiles, HiDef and Reach: the former for fully featured, high-powered hardware, and the latter for less featured, available-everywhere hardware. Reach is designed to broadly cover all platforms and has a limited set of graphic features and capabilities implemented in hardware. This profile is designed to support the widest variety of devices, more specifically Windows-based computers, mobiles and consoles. Reach dramatically speeds up writing multiplatform games because you can design and debug game code on one platform knowing that it will run on other platforms. Performance is dependent on the hardware available for each platform. + +The HiDef profile is designed for the highest performance and largest available set of graphic features. Use the HiDef profile to target hardware with more enhanced graphic capabilities such as an consoles and Windows-based computers with at least a DirectX 10 GPU. More specifically, the HiDef profile requires a GPU with console-level capabilities such as multiple render targets (MRT), floating-point surface formats, and per-vertex texture fetching. These are optional capabilities in DirectX 9 hardware, but all are required to support HiDef. Since DirectX 9 graphic cards are not required to support these features, it is easier to say that the HiDef profile requires at least a DirectX 10-capable GPU. A HiDef game will run on a DirectX 9 card if it implements the named DirectX 10 features. + +If you try to run a HiDef game on a device such as a mobile device) that does not support HiDef, an exception is thrown at runtime. Additionally, if you try to access HiDef features from a game built for a Reach profile, the runtime throws an exception. To find out which profile your target hardware supports, call [GraphicsAdapter.IsProfileSupported Method](/api/Microsoft.Xna.Framework.Graphics.GraphicsAdapter.html#Microsoft_Xna_Framework_Graphics_GraphicsAdapter_IsProfileSupported_Microsoft_Xna_Framework_Graphics_GraphicsProfile_). + +## Reach vs. HiDef Comparison + +Differences between the Reach and HiDef profiles are presented next. For more detail, see the sections following the table. + +|Profiles|Reach|HiDef| +|-|-|-| +|Platforms|Mobile, Consoles, and any computer running Windows with a DirectX 9 GPU that supports at least Shader Model 2.0.|Consoles, and any Windows-based PC with at least a DirectX 10 (or equivalent) GPU. See the paragraph above for more detail.| +|Shader Model|2.0 |3.0| +|Maximum texture size|2,048|4,096| +|Maximum cube map size|512|4,096| +|Maximum volume texture size|Volume textures are not supported.|256| +|Nonpower of two textures|Yes with limitations: no wrap addressing mode, no mipmaps, no DXT compression on nonpower of two textures.|Yes| +|Nonpower of two cube maps|No|Yes| +|Nonpower of two volume textures|Volume textures are not supported.|Yes| +|Maximum number of primitives per draw call|65,535|1,048,575| +|Maximum number of vertex streams|16|16| +|Maximum vertex stream stride|25|255| +|Index buffer formats|16 bit|16 and 32 bit| +|Vertex element formats|Color, Byte4, Single, Vector2, Vector3, Vector4, Short2, Short4, NormalizedShort2, NormalizedShort4|All of the Reach vertex element formats, as well as HalfVector2 and HalfVector4.| +|Texture formats|Color, Bgr565, Bgra5551, Bgra4444, NormalizedByte2, NormalizedByte4, Dxt1, Dxt3, Dxt5|All of the Reach texture formats, as well as Alpha8, Rg32, Rgba64, Rgba1010102, Single, Vector2, Vector4, HalfSingle, HalfVector2, HalfVector4. Floating point texture formats do not support filtering.| +|Vertex texture formats|Vertex texturing is not supported.|Single, Vector2, Vector4, HalfSingle, HalfVector2, HalfVector4| +|Render target formats|Call **QueryRenderTargetFormat** to find out what is supported.|Call **QueryRenderTargetFormat** to find out what is supported.| +|Multiple render targets|No|Up to four. All must have the same bit depth. Alpha blending and independent write masks per render target are supported.| +|Occlusion queries|No|Yes| +|Separate alpha blend|No|Yes|S + +## Shader Model + +The Reach profile supports HLSL Shader Model 2.0 and the configurable effects for all platforms. Some mobile platforms do not support custom shaders. + +The HiDef profile supports HLSL Shader Model 3.0. Consoles and desktop also support custom shader extensions such as vertex fetching (vfetch). + +## Textures + +Texture size limitations are listed in the table comparing the two profiles. These numbers are the maximum width or height of a texture that can be consumed by the profile. HiDef supports larger textures and volume textures. + +HiDef supports the following features without limitations; Reach supports the following features only for power-of-two textures: + +* The **wrap** texture addressing mode +* Mipmaps +* DXT compression + +## Formats + +There are a wide variety of render target formats. Call [GraphicsAdapter.QueryRenderTargetFormat Method](/api/Microsoft.Xna.Framework.Graphics.GraphicsAdapter.html#Microsoft_Xna_Framework_Graphics_GraphicsAdapter_QueryRenderTargetFormat_Microsoft_Xna_Framework_Graphics_GraphicsProfile_Microsoft_Xna_Framework_Graphics_SurfaceFormat_Microsoft_Xna_Framework_Graphics_DepthFormat_System_Int32_Microsoft_Xna_Framework_Graphics_SurfaceFormat__Microsoft_Xna_Framework_Graphics_DepthFormat__System_Int32__) to find out what is supported for your hardware. The runtime also has a built-in fallback mechanism if the format you request is unavailable. The format parameters used when creating render targets and back buffers are now named "preferredFormat" instead of "format." The runtime will try to create a resource with the exact format passed in, and will fallback to the closest possible match (based on similar bit depth, number of channels, and so on) if that format is unavailable. For example, if you run a Reach game on a Windows Phone device using a 16-bit render target format and then run the game on some consoles that do not support 16-bit render targets, the runtime will switch the render-target format to a [Color](xref:Microsoft.Xna.Framework.Color) format. + +## Conclusion + +XNA introduced the Reach profile for Consoles, Windows, and mobile, and the HiDef profile for Consoles and Windows devices. The HiDef profile includes a strict superset of the functionality in the Reach profile, which means that HiDef implements all Reach functionality and more. If you run a Reach game on a HiDef platform, the framework will enforce Reach rules. Use this to your advantage when you develop a multiplatform game. You can design and debug on the most powerful hardware with the knowledge that the game will compile and run on the other less powerful platforms when you are ready to test your game. The runtime will throw an exception if you try to set the profile to HiDef on hardware that does not support HiDef, or if you are running a Reach profile game that tries to access HiDef features. + +## Cited Works + +"Selecting Reach vs. HiDef." Shawn Hargreaves Blog. July 2010. [http://web.archive.org/web/20120102231201/http://blogs.msdn.com/b/shawnhar/archive/2010/07/19/selecting-reach-vs-hidef.aspx](http://web.archive.org/web/20120102231201/http://blogs.msdn.com/b/shawnhar/archive/2010/07/19/selecting-reach-vs-hidef.aspx) (Last accessed August 2, 2010) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/WhatIs_TheGameLoop.md b/articles/monogame/whatis/WhatIs_TheGameLoop.md new file mode 100644 index 0000000..1e77231 --- /dev/null +++ b/articles/monogame/whatis/WhatIs_TheGameLoop.md @@ -0,0 +1,100 @@ +--- +title: What is the Game Loop +description: The MonoGame Framework Game class implements a game loop, which provides not only the window which displays your game, but also provides overloadable methods that your game implements to facilitate communication between your game and the operating system. This topic provides an overview of the basic functionality provided by the game loop. +--- + +# Initializing a Game + +The MonoGame Framework [Game](xref:Microsoft.Xna.Framework.Game) class implements a game loop, which provides not only the window which displays your game, but also provides overloadable methods that your game implements to facilitate communication between your game and the operating system. This topic provides an overview of the basic functionality provided by the game loop. + +* [Making a New Game](#making-a-new-game) +* [Game Loop Timing](#game-loop-timing) +* [Game Components](#fixed-step-game-loops) +* [Game Services](#game-services) +* [Game Components Consuming Game Services](#game-components-consuming-game-services) + +## Making a New Game + +The first step in creating a new game is to make a class that derives from [Game](xref:Microsoft.Xna.Framework.Game). The new class needs to override the following methods: + +* Initialize - which is the method is responsible for game setup before the first frame of the game. +* Update - which is the method is responsible for handling game logic. +* Draw - which is the method responsible for drawing content to the screen. + +## Game Loop Timing + +A [Game](xref:Microsoft.Xna.Framework.Game) is either fixed step or variable step, defaulting to fixed step. The type of step determines how often [Update](xref:Microsoft.Xna.Framework.Game) will be called and affects how you need to represent time-based procedures such as movement and animation. + +## Fixed-Step Game Loops + +A fixed-step [Game](xref:Microsoft.Xna.Framework.Game) tries to call its **Update** method on the fixed interval specified in **TargetElapsedTime**. Setting **Game.IsFixedTimeStep** to **true** causes a [Game](xref:Microsoft.Xna.Framework.Game) to use a fixed-step game loop. A new MonoGame project uses a fixed-step game loop with a default **TargetElapsedTime** of 1/60th of a second. + +In a fixed-step game loop, [Game](xref:Microsoft.Xna.Framework.Game) calls **Update** once the **TargetElapsedTime** has elapsed. After **Update** is called, if it is not time to call **Update** again, the [Game](xref:Microsoft.Xna.Framework.Game) calls **Draw**. After **Draw** is called, if it is not time to call **Update** again, [Game](xref:Microsoft.Xna.Framework.Game) idles until it is time to call **UpdateS**. + +If **Update** takes too long to process, [Game](xref:Microsoft.Xna.Framework.Game) sets **IsRunningSlowly** to **true** and calls **Update** again, without calling **Draw** in between. When an update runs longer than the **TargetElapsedTime**, [Game](xref:Microsoft.Xna.Framework.Game) responds by calling **Update** extra times and dropping the frames associated with those updates to catch up. This ensures that **Update** will have been called the expected number of times when the game loop catches up from a slowdown. You can check the value of **IsRunningSlowly** in your **Update** if you want to detect dropped frames and shorten your **Update** processing to compensate. You can reset the elapsed times by calling **ResetElapsedTime**. + +When your game pauses in the debugger, [Game](xref:Microsoft.Xna.Framework.Game) will not make extra calls to **Update** when the game resumes. + +### Variable-Step Game Loops + +A variable-step game calls its **Update** and **Draw** methods in a continuous loop without regard to the [TargetElapsedTime](xref:Microsoft.Xna.Framework.Game). Setting [Game.IsFixedTimeStep](xref:Microsoft.Xna.Framework.Game) to **false** causes a [Game](xref:Microsoft.Xna.Framework.Game) to use a variable-step game loop. + +### Animation and Timing + +For operations that require precise timing, such as animation, the type of game loop your game uses (fixed-step or variable-step) is important. + +Using a fixed step allows game logic to use the **TargetElapsedTime** as its basic unit of time and assume that **Update** will be called at that interval. Using a variable step requires the game logic and animation code to be based on **ElapsedGameTime** to ensure smooth gameplay. Because the **Update** method is called immediately after the previous frame is drawn, the time between calls to **Update** can vary. Without taking the time between calls into account, the game would seem to speed up and slow down. The time elapsed between calls to the **Update** method is available in the **Update** method's _gameTime_ parameter. You can reset the elapsed times by calling **ResetElapsedTime**. + +When using a variable-step game loop, you should express rates—such as the distance a sprite moves—in game units per millisecond (ms). The amount a sprite moves in any given update can then be calculated as the rate of the sprite times the elapsed time. Using this approach to calculate the distance the sprite moved ensures that the sprite will move consistently if the speed of the game or computer varies. + +## Game Components + +Game components provide a modular way of adding functionality to a game. You create a game component by deriving the new component either from the [GameComponent](xref:Microsoft.Xna.Framework.GameComponent) class, or, if the component loads and draws graphics content, from the [DrawableGameComponent](xref:Microsoft.Xna.Framework.DrawableGameComponent) class. You then add game logic and rendering code to the game component by overriding **GameComponent.Update**, **DrawableGameComponent.Draw** and **GameComponent.Initialize**. A game component is registered with a game by passing the component to **Game.Components.Add**. A registered component will have its initialize, update, and draw methods called from the **Game.Initialize**, **Game.Update**, and **Game.Draw** methods, respectively. + +## Game Services + +Game services are a mechanism for maintaining loose coupling between objects that need to interact with each other. Services work through a mediator—in this case, [Game.Services](xref:Microsoft.Xna.Framework.Game.Services). Service providers register with [Game.Services](xref:Microsoft.Xna.Framework.Game.Services), and service consumers request services from [Game.Services](xref:Microsoft.Xna.Framework.Game.Services). This arrangement allows an object that requires a service to request the service without knowing the name of the service provider. + +Game services are defined by an interface. A class specifies the services it provides by implementing interfaces and registering the services with [Game.Services](xref:Microsoft.Xna.Framework.Game.Services). A service is registered by calling **Game.Services.AddService** specifying the type of service being implemented and a reference to the object providing the service. For example, to register an object that provides a service represented by the interface IMyService, you would use the following code. + +```csharp + Services.AddService( typeof( IMyService ), myobject ); +``` + +Once a service is registered, the object providing the service can be retrieved by **Game.Services.GetService** and specifying the desired service. For example, to retrieve [IGraphicsDeviceService](xref:Microsoft.Xna.Framework.Graphics.IGraphicsDeviceService), you would use the following code. + +```csharp + IGraphicsDeviceService graphicsservice = (IGraphicsDeviceService)Services.GetService( typeof(IGraphicsDeviceService) ); +``` + +## Game Components Consuming Game Services + +The [GameComponent](xref:Microsoft.Xna.Framework.GameComponent) class provides the [Game](xref:Microsoft.Xna.Framework.GameComponent.Game) property so a [GameComponent](xref:Microsoft.Xna.Framework.GameComponent) can determine what [Game](xref:Microsoft.Xna.Framework.Game) it is attached to. With the [Game](xref:Microsoft.Xna.Framework.GameComponent.Game) property, a [GameComponent](xref:Microsoft.Xna.Framework.GameComponent) can call [Game.Services.GetService](xref:Microsoft.Xna.Framework.GameServiceContainer) to find a provider of a particular service. For example, a [GameComponent](xref:Microsoft.Xna.Framework.GameComponent) would find the [IGraphicsDeviceService](xref:Microsoft.Xna.Framework.Graphics.IGraphicsDeviceService) provider by using the following code. + +```csharp + IGraphicsDeviceService graphicsservice = (IGraphicsDeviceService)Game.Services.GetService( typeof( IGraphicsDeviceService ) ); +``` + +## Related articles + +[Creating a Full-Screen Game](../howto/graphics/HowTo_FullScreen.md) + +Demonstrates how to start a game in full-screen mode. + +[Resizing a Game](../howto/HowTo_PlayerResize.md) + +Demonstrates how to resize an active game window. + +[Restricting Aspect Ratio on a Graphics Device](../howto/graphics/HowTo_AspectRatio.md) + +Demonstrates how to create a custom [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) that only selects graphics devices with widescreen aspect ratios in full-screen mode. + +[Automatic Rotation and Scaling](../howto/HowTo_AutomaticRotation.md) + +Describes rotation and scaling in the MonoGame Framework on Mobile Platforms. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/WhatIs_VectorMatrixQuat.md b/articles/monogame/whatis/WhatIs_VectorMatrixQuat.md new file mode 100644 index 0000000..6344b93 --- /dev/null +++ b/articles/monogame/whatis/WhatIs_VectorMatrixQuat.md @@ -0,0 +1,69 @@ +--- +title: What are Vectors, Matrices, and Quaternions? +description: What are What are Vectors, Matrices, and Quaternions definitions for MonoGame! +--- + +# What are Vectors, Matrices, and Quaternions? + +The MonoGame Framework Math Libraries are in the [Microsoft.Xna.Framework](xref:Microsoft.Xna.Framework) namespace alongside a number of additional types that deal with The MonoGame Framework Application model. + +* [Coordinate system](#coordinate-system) +* [Mathematical Constants and Scalar Manipulation](#mathematical-constants-and-scalar-manipulation) +* [Basic Geometric Types](#basic-geometric-types) +* [Precision and Performance](#precision-and-performance) + +## Coordinate system + +The MonoGame Framework uses a right-handed coordinate system, with the positive z-axis pointing toward the observer when the positive x-axis is pointing to the right, and the positive y-axis is pointing up. + +## Mathematical Constants and Scalar Manipulation + +The MonoGame Framework provides the [MathHelper Members](xref:Microsoft.Xna.Framework.MathHelper) class for manipulating scalar values and retrieving some common mathematical constants. This includes methods such as the ```ToDegrees``` and ```ToRadians``` utility methods for converting between degrees and radians. + +## Basic Geometric Types + +The MonoGame Framework Math library has multiple basic geometric types for manipulating objects in 2D or 3D space. Each geometric type has a number of mathematical operations that are supported for the type. + +### Vectors + +The MonoGame Framework provides the [Vector2](xref:Microsoft.Xna.Framework.Vector2), [Vector3](xref:Microsoft.Xna.Framework.Vector3), and [Vector4](xref:Microsoft.Xna.Framework.Vector4) classes for representing and manipulating vectors. A vector typically is used to represent a direction and magnitude. In The MonoGame Framework, however, it also could be used to store a coordinate or other data type with the same storage requirements. + +Each vector class has methods for performing standard vector operations such as: + +* [Dot product](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_Dot_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_) +* [Cross product](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_Cross_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_) +* [Normalization](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_Normalize) +* [Transformation](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_Transform_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Matrix_) +* [Linear](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_Lerp_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_System_Single_), [Cubic](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_SmoothStep_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_System_Single_), [Catmull-Rom](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_CatmullRom_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_System_Single_), or [Hermite spline](/api/Microsoft.Xna.Framework.Vector3.html#Microsoft_Xna_Framework_Vector3_Hermite_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_Microsoft_Xna_Framework_Vector3_System_Single_) interpolation. + +### Matrices + +The MonoGame Framework provides the [Matrix](xref:Microsoft.Xna.Framework.Matrix) class for transformation of geometry. The [Matrix](xref:Microsoft.Xna.Framework.Matrix) class uses row major order to address matrices, which means that the row is specified before the column when describing an element of a two-dimensional matrix. The [Matrix](xref:Microsoft.Xna.Framework.Matrix) class provides methods for performing standard matrix operations such as calculating the ```determinate``` or ```inverse``` of a matrix. There also are helper methods for creating scale, rotation, and translation matrices. + +### Quaternions + +The MonoGame Framework provides the [Quaternion](xref:Microsoft.Xna.Framework.Quaternion) structure to calculate the efficient rotation of a vector by a specified angle. + +### Curves + +The [Curve](xref:Microsoft.Xna.Framework.Curve) class represents a hermite curve for interpolating varying positions at different times without having to explicitly define each position. The curve is defined by a collection of [CurveKey](xref:Microsoft.Xna.Framework.CurveKey) points representing each varying position at different times. This class can be used not only for spatial motion, but also to represent any response that changes over time. + +### Bounding Volumes + +The MonoGame Framework provides the [BoundingBox](xref:Microsoft.Xna.Framework.BoundingBox), [BoundingFrustum](xref:Microsoft.Xna.Framework.BoundingFrustum), [BoundingSphere](xref:Microsoft.Xna.Framework.BoundingSphere), [Plane](xref:Microsoft.Xna.Framework.Plane), and [Ray](xref:Microsoft.Xna.Framework.Ray) classes for representing simplified versions of geometry for the purpose of efficient collision and hit testing. These classes have methods for checking for intersection and containment with each other. + +## Precision and Performance + +The MonoGame Framework Math libraries are single-precision. This means that the primitives and operations contained in this library use 32-bit floating-point numbers to achieve a balance between precision and efficiency when performing large numbers of calculations. + +A 32-bit floating-point number ranges from ```–3.402823e38``` to ```+3.402823e38```. The 32 bits store the sign, mantissa, and exponent of the number that yields seven digits of floating-point precision. + +> Some numbers—for example π, 1/3, or the square root of two—can be approximated only with seven digits of precision, so be aware of rounding errors when using a binary representation of a floating-point number. + +For more information about single-precision numbers, see the documentation for the [Single](http://msdn.microsoft.com/en-us/library/system.single.aspx) data type. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_AddCustomProcImp.md b/articles/monogame/whatis/content_pipeline/CP_AddCustomProcImp.md new file mode 100644 index 0000000..1e274c7 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_AddCustomProcImp.md @@ -0,0 +1,32 @@ +--- +title: What is a Custom Importer? +description: MonoGame provides standard importers and processors for a number of common file formats used to store such basic game assets as models, materials effects, sprites, textures, and so on. For a list of file formats supported by these standard importers and processors. +--- + +# Adding a Custom Importer + +MonoGame provides standard importers and processors for a number of common file formats used to store such basic game assets as models, materials effects, sprites, textures, and so on. For a list of file formats supported by these standard importers and processors, see [Standard Content Importers and Content Processors](CP_StdImpsProcs.md). + +## To add a custom importer or processor to a game project + +This procedure assumes you have copied the new importer or processor to a local folder in the game project. + +1. Open the MonoGame Pipeline Tool. +2. Load the .mgcb files associated with your game. +3. Click on the Content node and in the Properties panel click on References. +4. Click the Add Button. +5. Navigate to the directory containing the assembly with the custom importer or processor, and then add it. +6. Save. + +The new importer or processor now appears as a choice in dialog properties for importing or processing a newly added game asset. + +## See Also + +- [Adding New Content Types](CP_Content_Advanced.md) +- [Standard Content Importers and Content Processors](CP_StdImpsProcs.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_Architecture.md b/articles/monogame/whatis/content_pipeline/CP_Architecture.md new file mode 100644 index 0000000..a76c046 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_Architecture.md @@ -0,0 +1,62 @@ +--- +title: What is the Content Pipeline Architecture? +description: The Content Pipeline is designed to be extensible, so that it can easily support new input file formats and new types of conversion. +--- + +# What is the Content Pipeline Architecture? + +The MonoGame Content Pipeline is a set of processes applied when a game that includes art assets is built. The process starts with an art asset in its original form as a file, and continues to its transformation as data that can be retrieved and used within a MonoGame game through the MonoGame Framework Class Library. + +The Content Pipeline is designed to be extensible, so that it can easily support new input file formats and new types of conversion. + +Most MonoGame developers can ignore the inner workings of the Content Pipeline. The most commonly used types of game assets and formats are inherently supported by MonoGame. However, if you are a game developer who needs to support a new file format or game-engine capability, it is useful to understand the stages of the Content Pipeline that transform an asset from a digital-content creation (DCC) output file to part of the game binary. + +## Content Pipeline Components + +A game asset is made available to an MonoGame game after it is added to the Content project. Once the asset is part of the game solution, it is included in the Content Pipeline. + +Processes fall into two types depending on when they execute: design time components and runtime components. + +### Design-Time Components + +The design-time components of the MonoGame Content Pipeline that process your game assets execute when you build your MonoGame game as an executable file. These processes perform the initial transformation of an asset from its digital content creation (DCC) format to a managed code object that your game can use upon execution. + +Design-time components use the [Content Pipeline Class Library](CP_Class_Library.md), which can be used and extended to create custom Content Pipeline design-time components. + +#### Content Importer + +A _Content Importer_ converts game assets from a particular DCC file format into objects in the MonoGame Content Document Object Model (DOM) that standard Content Processors can consume, or into some other custom form that a particular custom Content Processor can consume. + +An Content Importer typically converts content into managed objects based on the Content DOM, which includes strong typing for such assets as meshes, vertices, and materials. A custom Content Importer, however, may produce custom objects for a particular custom Content Processor to consume. + +#### Content Processor + +A _Content Processor_ takes one specific type of an imported game asset and compiles it into a managed code object that can be loaded and used by MonoGame games. + +Each Content Processor acts upon a specific object type. For example, the [Effect Processor](CP_StdImpsProcs.md#standard-content-processors) accepts only [EffectContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.EffectContent) objects, representing a DirectX Effect asset. + +When you include a game asset file in your MonoGame .mgcb file, its **dialog properties** page specifies the appropriate Content Importer and Content Processor. Thereafter, when you build your game (by pressing F5), the assigned Content Importer and Content Processor for each asset is invoked automatically. The asset is built into your game in a form that can be loaded at run time by your game. + +The managed code objects created by the Content Processor are serialized into a compact binary format (also referred to as an intermediate format) file with an .XNB extension by the Content Pipeline Content Compiler. This .XNB file is used by the runtime components of the Content Pipeline that assist your game in retrieving the transformed game assets. + +The format of data in the .XNB file is tightly coupled to the MonoGame Framework. It is not designed for use by other runtime libraries. + +### Runtime Components + +Runtime components of the Content Pipeline support loading and using the transformed game asset by your MonoGame game. These components use the [MonoGame library](../WhatIs_MonoGame_Class_Library.md), which can be extended to create custom components. + +Content Loader + +When the game needs the game asset's managed code object, it must call the [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager) method to invoke the Content Loader, specifying the object type it expects. The Content Loader then locates and loads the asset from the compact binary format (.XNB) file into the memory space of the game where it can be used. + +## See Also + +- [What Is Content?](CP_Overview.md) +- [Adding New Content Types](CP_Content_Advanced.md) +- [Loading Additional Content Types](CP_Customizing.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_Class_Library.md b/articles/monogame/whatis/content_pipeline/CP_Class_Library.md new file mode 100644 index 0000000..210dbf9 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_Class_Library.md @@ -0,0 +1,49 @@ +--- +title: Content Pipeline Class Library +description: Content Pipeline Class Library Reference +--- + +# Content Pipeline Class Library + +The Content Pipeline class library is a library of classes, interfaces, and value types that are included in MonoGame. This library provides access to MonoGame Framework Content Pipeline functionality and is designed to be the foundation on which Content Pipeline–related applications, components, and controls are built. + +## Namespaces + +- [Microsoft.Xna.Framework.Content.Pipeline](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.html) + + Provides classes representing base types and building block functionality for use by more specialized object models, such as the Graphics DOM. + +- [Microsoft.Xna.Framework.Content.Pipeline.Audio](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.Audio.html) + + Provides intermediate classes and types for representing and manipulating graphics audio data. + +- [Microsoft.Xna.Framework.Content.Pipeline.Graphics](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.Graphics.html) + + Provides intermediate classes and types for representing and manipulating graphics data. + +- [Microsoft.Xna.Framework.Content.Pipeline.Processors](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.Processors.html) + + Provides base classes that represent processors used by the MonoGame Framework Content Pipeline when processing specific game asset types. + +- [Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler.html) + + Provides base classes that represent compilers and writers used by the MonoGame Framework Content Pipeline when processing specific game asset types. + +- [Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate](https://monogame.net/api/Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.html) + + Provides base classes that represent the creation and writing of intermediate content for game asset types processed by the XNA Framework Content Pipeline. + +- Microsoft.Xna.Framework.Content.Pipeline.Tasks + + Provides support for importing and processing game assets into the binary format that is used by the Content Loader of a game project. + +## See Also + +- [Adding Content to a Game](index.md) +- [What Is Content?](CP_Overview.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_Content_Advanced.md b/articles/monogame/whatis/content_pipeline/CP_Content_Advanced.md new file mode 100644 index 0000000..9126b76 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_Content_Advanced.md @@ -0,0 +1,52 @@ +--- +title: What are custom content types? +description: Content Builders and Processors can be customized to handle almost any content type. +--- + +# Adding New Content Types + +The MonoGame Content Pipeline builds game assets included in your project into a form your game can load at run time. + +This game asset build process is controlled by Content Pipeline importers and content processors. When you press F5 to build a game created with MonoGame, the appropriate Content Pipeline importer and processor for each asset is invoked. Each asset then is automatically built into your game. + +The flexibility of this process enables you to create and update game assets using a variety of digital content creation (DCC) tools. MonoGame supplies importers for several popular export formats supported by DCC tools, and also lets you develop custom importers for other formats. + +## In This Section + +- [What is the Content Pipeline Architecture?](CP_Architecture.md) + + Describes the components and execution flow of the MonoGame Content Pipeline. + +- [Content Pipeline Document Object Model](CP_DOM.md) + + Describes the built-in object support features for assets in the Content Pipeline. + +- [Loading Additional Content Types](CP_Customizing.md) + + Describes the options for customizing the Content Pipeline to support nonstandard game assets or special-purpose needs. + +- [Tips for Developing Custom Importers and Processors](CP_Tips_For_Developing.md) + + Provides useful information about how to design and debug a custom Content Pipeline importer or processor. + +- [Adding a Custom Importer](CP_AddCustomProcImp.md) + + Describes how to add a custom processor or importer to an existing game solution. + +- [Extending a Standard Content Processor](../../howto/Content_Pipeline/HowTo_Extend_Processor.md) + + Describes how MonoGame lets you modify or extend the behavior of any standard Content Pipeline processor that ships with the product. + +- [Developing with Parameterized Processors](CP_CustomParamProcs.md) + + Describes how to develop with parameterized processors, both standard and custom. + +- [How to: Extend the Font Description Processor to Support Additional Characters](../../howto/Content_Pipeline/HowTo_ExtendFontProcessor.md) + + Describes the process of developing a custom content processor needed to add additional characters to a [FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription) object based on the text that is required by the game. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_CustomParamProcs.md b/articles/monogame/whatis/content_pipeline/CP_CustomParamProcs.md new file mode 100644 index 0000000..f2aaeb8 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_CustomParamProcs.md @@ -0,0 +1,126 @@ +--- +title: What are Parameterized Processors? +description: This topic discusses a method for programmatically modifying existing parameter values, and for adding new parameters to your own processors. +--- + +# Developing with Parameterized Processors + +This topic discusses a method for programmatically modifying existing parameter values, and for adding new parameters to your own processors. + +## Programmatically Setting Parameter Values + +When you need to pass parameter values from one processor to another (also referred to as chaining), use the [BuildAsset](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext) and [BuildAndLoadAsset](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext) methods. Pass the parameter and its value using the _processorParameters_ argument of the respective method. For example, a custom model processor would invoke a second processor for model textures with a call to [BuildAsset](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext) and pass any parameter values in the _processorParameters_ argument. + +The following code example demonstrates this technique. First, add several parameters to a data dictionary: + +```csharp + //create a dictionary to hold the processor parameter + OpaqueDataDictionary parameters = new OpaqueDataDictionary(); + + //add several parameters to the dictionary + parameters.Add( "ColorKeyColor", Color.Magenta ); + parameters.Add( "ColorKeyEnabled", true ); + parameters.Add( "ResizeToPowerOfTwo", true ); +``` + +After adding the necessary parameters, pass the dictionary to the chained processor: + +```csharp + context.BuildAsset( + texture, typeof( TextureProcessor ).Name, + parameters, + null, + null ); +``` + +This call passes all parameters (stored in `parameters`) to a texture processor. + +Again, any parameters not recognized by the receiving processor are ignored. Therefore, if the parameter `ColorKeyCode` is entered into the dictionary as _ColourKeyCode_, it is ignored by the receiving processor. + +## Declaring Process Parameters + +Adding one or more parameters to your custom processor requires additional code in your processor's definition. Parameters support the following types: + +- bool +- byte +- sbyte +- char +- decimal +- double +- float +- int +- uint +- long +- ulong +- short +- ushort +- string +- enum +- [Vector2](xref:Microsoft.Xna.Framework.Vector2), [Vector3](xref:Microsoft.Xna.Framework.Vector3), and [Vector4](xref:Microsoft.Xna.Framework.Vector4) +- [Color](xref:Microsoft.Xna.Framework.Color) + +Parameters of other types are ignored by the processor. + +> **Tip** +> +> Apply the Browsable attribute (with a value of **false**) to an individual parameter to prevent that parameter from being displayed in the Properties window. + +The following code example defines a simple custom processor that switches the coordinate system of a model using a single parameter (called switchCoordinateSystem): + +```csharp + public class SwitchCoordSystemProcessor : ModelProcessor + { + #region Processor Parameters + private bool switchCoordinateSystem = false; + + [DisplayName("Switch Coordinate System")] + [DefaultValue(false)] + [Description("Switches the coordinate system of a model.")] + public bool SwitchCoordinateSystem + { + get { return switchCoordinateSystem; } + set { switchCoordinateSystem = value; } + } + //additional class code follows... +``` + +In this code, the `SwitchCoordSystemProcessor` class is derived from [ModelProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor). This indicates that the processor accepts a model as input. The next few lines declare a single property called `SwitchCoordinateSystem` of type **bool**. Note that every parameter must have a **set*- method. The property also has several attributes applied to it: + +|Attribute name|Usage| +|-|-| +|DisplayName|Name of the property when it appears in the Properties window of the MonoGame Pipeline tool. If not specified, the internal property name, declared in the source code, is used. For this example, "Switch Coordinate System" would be displayed.| +|DefaultValue|A user interface (UI) hint specifying the possible default value of the property. This value is used only as a UI hint; it will not be set on the property, nor will it override the default value declared in the code.| +|Description|Descriptive text displayed when you select the property in the Properties window of the MonoGame Pipeline Tool.| + +This completes the definition of the `SwitchCoordinateSystem` property. + +In the next code example, the class definition is continued with an override of the [Process](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor) method: + +```csharp + //additional class code precedes... + + public override ModelContent Process(NodeContent input, ContentProcessorContext context) + { + if (switchCoordinateSystem) + { + Matrix switchMatrix = Matrix.Identity; + switchMatrix.Forward = Vector3.Backward; + MeshHelper.TransformScene(input, switchMatrix); + } + + return base.Process(input, context); + } +``` + +This code passes the `SwitchCoordinateSystem` property (declared earlier) value to [TransformScene](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshHelper), which is a helper method that applies a transform to a scene hierarchy. + +## See Also + +- [Adding New Content Types](CP_Content_Advanced.md) +- [Parameterized Content Processors](CP_StdParamProcs.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_Customizing.md b/articles/monogame/whatis/content_pipeline/CP_Customizing.md new file mode 100644 index 0000000..c0369e8 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_Customizing.md @@ -0,0 +1,65 @@ +--- +title: Loading Additional Content Types? +description: MonoGame provides the capability to extend Content Pipeline components that import and process almost any game asset file type. +--- + +# Loading Additional Content Types + +MonoGame provides standard Content Pipeline components that import and process the most commonly used game asset file types. These file types include, for example, Content Importers for the Autodesk (.fbx) format and the DirectX (.x) format. A complete list of file types is available in the [Standard Content Importers and Content Processors](CP_StdImpsProcs.md) topic. Most digital Content creation (DCC) tools are capable of creating output in at least one of these standard formats. + +## Choosing to Customize + +A custom Content Importer is required for game assets available only in formats unsupported by MonoGame standard Content Importers. One may already be available from a third party. Custom Content Importers can be developed by DCC vendors, game-engine developers, and interested game hobbyists. Once a custom Content Importer is installed on your computer, you can associate art files with the Content Importer to invoke it when you build the art files (see [Adding a Custom Importer](CP_AddCustomProcImp.md)). + +You may need to write your own custom MonoGame Content Pipeline components to: + +- Support a new type of game asset or format from a DCC tool. +- Derive special-purpose content from another piece of content at the time the game is built. + +Here are some typical scenarios, and a summary of which Content Pipeline components require customization. + +|Component|When to customize|Output options| +|-|-|-| +|Content Importer|
  • A game asset created by a DCC tool is available only in a format unsupported by a MonoGame standard Content Importer.
|
  1. [Content Document Object Model](CP_DOM.md) (DOM) object that can be consumed by a standard Content Processor.
  2. A custom object that must be consumed by a custom Content Processor.
| +|Content Processor|
  • Must process the custom output of a custom Content Importer.
  • Needs to process the output of a standard Content Importer in a special-purpose way.
|
  1. A standard Content Processor output type.
  2. A custom Content Processor output type that must be consumed by a custom Content Loader at game run time.
| +|Content Loader|
  • Must load custom output of a customized Content Processor.
  • A custom Content Loader is implemented by extending the [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager) method to load the new custom data type.
  • |
    1. A standard MonoGame Framework class object.
    2. A custom class object.
    | + +## Customization Scenarios + +This section examines some typical examples where customization is needed, and illustrates which Content Pipeline components must be changed. + +### Supporting a New File Format + +In this example, a nonstandard file format contains information that can be represented by a standard Content DOM type. + +![Custom Importer DOM](../images/CP_CustomImporter.png) + +As illustrated, only a custom Content Importer that can read the nonstandard file format and output a Content DOM object (in this case, a **TextureContent** object) is required. The remainder of the Content Pipeline process can be performed by a standard Content Processor and Content Loader. + +### Creating Special-Purpose Data from Standard Objects + +For this example, a texture object that represents a map of normalized vectors derived from the original texture object is created. + +![Sprite Importer DOM](../images/CP_CustomImporter.png) + +Since the texture is contained in a standard format for the game asset, a standard Content Importer can be used to create the **TextureContent** object. A custom Content Processor (**NormalMapProcessor**) creates the special-purpose data, but uses the standard **TextureContent** class to contain the result so that it can be loaded by the standard Content Loader. + +## Supporting Custom Data from a Nonstandard Game Asset + +Illustrated in this example is a nonstandard game asset file containing data that does not correspond to any standard data types. + +![Custom Importer DOM](../images/CP_CustomData.png) + +To read the nonstandard game asset file, a custom Content Importer is required that outputs a **CustomContent** object. Since the output of the Content Importer is a custom class, a custom Content Processor also is needed, and the [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager) method must be extended to support the custom data object. + +## See Also + +- [Adding New Content Types](CP_Content_Advanced.md) +- [What Is Content?](CP_Overview.md) +- [What is the Content Pipeline?](CP_Architecture.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_DOM.md b/articles/monogame/whatis/content_pipeline/CP_DOM.md new file mode 100644 index 0000000..4ea55ff --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_DOM.md @@ -0,0 +1,27 @@ +--- +title: What is the Content Pipeline Document Object Model? +description: The MonoGame Content Document Object Model (DOM) represents the set of built-in classes that can be consumed by standard content processors. +--- + +# Content Pipeline Document Object Model + +The MonoGame Content Document Object Model (DOM) represents the set of built-in classes that can be consumed by standard content processors. + +Currently, the DOM provides support for meshes, materials, textures, sprite-fonts, and animations. Outside of these, a custom importer can return a [ContentItem](xref:Microsoft.Xna.Framework.Content.Pipeline.ContentItem) with custom information in its opaque data, or a custom type you have developed. + +The following diagram lists the complete Content DOM. + +![Content DOM](../images/ContentPipelineTypes_small.png) + +## See Also + +- [What Is Content?](CP_Overview.md) +- [What is the Content Pipeline?](CP_Architecture.md) +- [Extending a Standard Content Processor](../../howto/Content_Pipeline/HowTo_Extend_Processor.md) +- [Adding New Content Types](CP_Content_Advanced.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_Overview.md b/articles/monogame/whatis/content_pipeline/CP_Overview.md new file mode 100644 index 0000000..139cae0 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_Overview.md @@ -0,0 +1,75 @@ +--- +title: What Is Content? +description: Content is all the parts of your game that are not executing managed code. It includes all art assets, such as textures, sprites, meshes, effects, and fonts; and includes sound assets, such as music or brief sound effects. It also can include data assets, such as tables of levels or character attributes. +--- + +# What Is Content? + +The MonoGame Content Pipeline is a set of processes applied to a game's art and data assets when the game is built. The process starts with an art asset in its original form as a file, and it continues to its transformation as data that can be retrieved and used within a MonoGame game through the MonoGame Framework Class Library. + +Content is all the parts of your game that are not executing managed code. It includes all art assets, such as textures, sprites, meshes, effects, and fonts; and includes sound assets, such as music or brief sound effects. It also can include data assets, such as tables of levels or character attributes. + +Most content will be created using a digital content creation (DCC) tool, such as a paint program or a 3D model editor. The content your game uses is stored in a variety of file formats. Most will be standard file formats, such as JPEG for textures or Autodesk FBX format for 3D models. However, they might also be in a custom format or house custom data in XML format. + +## Benefits of the Content Pipeline + +The chief reason MonoGame uses a Content Pipeline is to help your game run fast. Without the content pipeline, your game would have to be built with its art assets in their original file format. When the game needs to load its art to draw it on the screen, it would have to determine its format and convert the data into a form it can use more directly. This would have to be performed at run time, for each asset, making the player wait to have fun. + +The Content Pipeline remedies this by shifting this time-consuming work to when the game is built. At build time, each asset is imported from its original file format and processed into a managed code object. Those objects are then serialized to a file that is included in the game’s executable. + +At run time, the game can then read the serialized data from the file directly into a managed code object for immediate use. + +This architecture also provides several other benefits. + +- Game artists can use the DCC tools of their choice. +- Game developers can use the files game artists produce directly in their MonoGame projects. +- If all game assets are in file formats supported by the [Standard Importers and Processors](CP_StdImpsProcs.md) provided by MonoGame, the game developer never needs to be concerned with the specifics of that file format, nor possess a detailed knowledge of how the Content Pipeline works. +- If required, the Content Pipeline can easily be customized or extended to import a new file format or to produce custom output. + +## Using the Content Pipeline + +For MonoGame games that use the most common types of art assets and formats, a detailed knowledge of how the Content Pipeline works is unnecessary. MonoGame supplies standard importers and processors for many popular DCC file formats. The only procedure necessary is to add these assets to the game's content project. For a list of formats MonoGame inherently supports, see [Standard Content Importers and Content Processors](CP_StdImpsProcs.md). + +To use a DirectX Effect (.fx) file in your game, for example, just [add](../../howto/Content_Pipeline/HowTo_GameContent_Add.md) the file to the MonoGame game content project (.mgcb). The MonoGame Pipeline tool recognizes the .fx file type as one it supports, and it assigns the correct components to it that are used to process it when the game is built. The game then can access the effect through the standard [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager) method of the MonoGame Framework. The game programmer does not need to be concerned about all the steps taken by the Content Pipeline to ready it for this straightforward use. + +There are other circumstances, however, when it helps to understand how the Content Pipeline works. + +- A third party may provide custom MonoGame Content Pipeline components that support additional art assets and formats. +- You may need to write your own custom MonoGame Content Pipeline components to support a new type of art asset or format from a DCC. +- You may wish to write your own custom MonoGame Content Pipeline components to derive special-purpose content from another piece of content at the time the game is built. + +## Content Pipeline Components + +The processes that comprise the MonoGame Content Pipeline fall into two types, depending on when they execute: build-time components and run-time components. + +### Build-Time Components + +The build-time components of the Content Pipeline that process your art assets execute within Visual Studio when you build your MonoGame game and produce an executable file. These processes perform the initial transformation of an asset from a DCC format to a managed code object that your game can use when it executes. + +These build-time components make use of the [Content Pipeline Class Library](CP_Class_Library.md), which can be used and extended to create custom Content Pipeline build-time components. + +|Component|Description| +|-|-| +|Importer|An _importer_ converts art assets from a particular DCC file format to objects in the MonoGame [Content Document Object Model](CP_DOM.md) that standard content processors can consume, or to some other custom form that a particular custom processor can consume.| +|Content processor|A _processor_ takes one specific type of imported art asset, such as a set of meshes, and compiles it into a managed code object that can be loaded and used by MonoGame games at runtime.| + +When you include an art asset file in your MonoGame solution's content project (.mgcb), its Properties page in the Pipeline tool specifies the appropriate importer and processor. Thereafter, when you build your game (by pressing F5), the assigned importer and processor for each asset is invoked automatically. The asset is built into your game in a form that can be loaded at run time by your game by using [ContentManager.Load](xref:Microsoft.Xna.Framework.Content.ContentManager). + +## Run-time Components + +The run-time components of the MonoGame Content Pipeline support the loading and use of the transformed art asset by your MonoGame. + +These run-time components make use of the [MonoGame Framework Class Library](../WhatIs_MonoGame_Class_Library.md), which can be extended to create custom Content Pipeline run-time components. + +## See Also + +### Concepts + +- [Adding Content to a Game](index.md) +- [Adding New Content Types](CP_Content_Advanced.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_SpriteFontSchema.md b/articles/monogame/whatis/content_pipeline/CP_SpriteFontSchema.md new file mode 100644 index 0000000..f7c8a4e --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_SpriteFontSchema.md @@ -0,0 +1,83 @@ +--- +title: What is Sprite Font XML Schema Reference? +description: Describes the valid tags and values for Sprite-Font (.spritefont) XML files used by the Content Pipeline to create SpriteFont textures. +--- + +# Sprite Font XML Schema Reference + +Describes the valid tags and values for Sprite-Font (.spritefont) XML files used by the Content Pipeline to create [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) textures. + +|Tag name|Content type|Content description| +|-|-|-| +|``|string|The name of the font to be imported. This is not the name of a font file, but rather the friendly name that identifies the font once it is installed on your computer. You can use the **Fonts** folder in Control Panel to see the names of fonts installed on your system, and to install new ones as well. The Content Pipeline supports the same fonts as the [System.Drawing.Font](http://msdn.microsoft.com/en-us/library/system.drawing.font.aspx) class, including TrueType fonts, but not bitmap (.fon) fonts.| +|``|float|The point size of the font to be imported.| +|``|float|The number of pixels to add between each character when the string is rendered.| +|``|Boolean|Specifies whether to use kerning information when rendering the font. Default value is **true**.| +|` + + + 32 + 127 + + + + +``` + +Here is a sample localized .spritefont file: + +```xml + + + + Courier New + 18 + 0 + true + + + + 32 + 127 + + + + Strings.resx + Strings-fr.resx + + + +``` + +## See Also + +- [Adding Content to a Game](../../howto/Content_Pipeline/HowTo_GameContent_Add.md) + +### Reference + +- [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_StdImpsProcs.md b/articles/monogame/whatis/content_pipeline/CP_StdImpsProcs.md new file mode 100644 index 0000000..049262d --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_StdImpsProcs.md @@ -0,0 +1,54 @@ +--- +title: What are the Standard Content Importers and Content Processors? +description: Describes the standard Content Pipeline Content Importers and Content Processors of MonoGame that support various common art asset file formats. +--- + +# Standard Content Importers and Content Processors + +Describes the standard Content Pipeline Content Importers and Content Processors of MonoGame that support various common art asset file formats. + +Content Importers and Content Processors are implemented as assemblies. In addition to the standard ones provided by MonoGame and listed below, you can also use custom Content Importers and Content Processors developed by you or third parties. Use the Properties window to assign an appropriate Content Importer and Content Processor to each game asset added to your game project. + +## Standard Content Importers + +The following is a description of the standard Content Importers shipped with MonoGame and the type of game asset each supports. + +All standard Content Importers are declared as part of the Microsoft.Xna.Framework.Content.Pipeline namespace. + +| Name | Type name | Output type | Description +| ------------- |:-------------:| :----- | :---- | +| Autodesk FBX|FbxImporter|[NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent)|Imports game assets specified with the Autodesk FBX file format (.fbx). This Content Importer is designed to work with assets exported with the 2013 version of the FBX exporter. | +| Effect|EffectImporter|[EffectContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.EffectContent)|Imports a game asset specified with the DirectX Effect file format (.fx). | +| Sprite Font Description|FontDescriptionImporter|[FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription)|Imports a font description specified in a .spritefont file.| +| Texture|TextureImporter|[TextureContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|Imports a texture. These file types are supported: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga.| +| X File|XImporter|[NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent)|Imports game assets specified with the DirectX X file format (.x). This Content Importer expects the coordinate system to be left-sided.| +| XML Content|XmlImporter|object|Imports XML content used for editing the values of a custom object at run time. For instance, you could pass XML code to this Content Importer that looks for the specified property of a custom type and changes it to the specified value. You could then process the custom object with a Content Processor or pass it to your game untouched using the No Processing Required Content Processor.This Content Importer is designed for scenarios like importing an XML file that describes game data at run time (similar to the Sprite Font Description Content Importer) or importing terrain data in an XML file that then is passed to a Content Processor that generates a random terrain grid using that data.| +| Other 3D Content|OpenAssetImporter|[NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent)|Imports game assets specified with one of the formats supported by assimp. A sample of supported files types are: .dae, .3ds, .blend, .obj, .fbx (v2013). More are available see [Assimp Supported File Formats](https://github.com/assimp/assimp#supported-file-formats) for more details. Note some formats might not behave correctly with the standard [ModelProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor).| + +# Standard Content Processors + +MonoGame ships with a variety of Content Processors that support several common game asset types. Many of the standard Content Processors, such as the [TextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessor), support parameters for modifying the default behavior of the Content Processor. For more information, see [Parameterized Content Processors](CP_StdParamProcs.md). + +The following describes the standard Content Processors and the type of game asset each supports. + +| Name| Type name| Input type| Output type| Description| +| ----------------- |:-------------:| :----- | :---- | :---- | +| Model|[ModelProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor)|[NodeContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent)|[ModelContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelContent)|A parameterized Content Processor that outputs models as a [ModelContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelContent) object.
    Available parameters:
    * Color Key Color–Any valid [Color](xref:Microsoft.Xna.Framework.Color). [Magenta](xref:Microsoft.Xna.Framework.Color) is the default value.
    * Color Key Enabled–A Boolean value indicating if color keying is enabled. The default value is **true**.
    * Generate Mipmaps–A Boolean value indicating if mipmaps are generated. The default value is **false**.
    * Generate Tangent Frames–A Boolean value indicating if tangent frames are generated. The default value is **false**.
    * Resize Textures to Power of Two–A Boolean value indicating if a texture is resized to the next largest power of 2. The default value is **false**.
    * Scale–Any valid [float](http://msdn.microsoft.com/en-us/library/system.single.aspx) value. The default value is 1.0.
    * Swap Winding Order–A Boolean value indicating if the winding order is swapped. This is useful for models that appear to be drawn inside out. The default value is **false**.
    * Texture Format–Any valid [SurfaceFormat](xref:Microsoft.Xna.Framework.Graphics.SurfaceFormat) value. Textures are either unchanged, converted to the Color format, or DXT Compressed. For more information, see [TextureProcessorOutputFormat](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessorOutputFormat).
    * X Axis Rotation–Number, in degrees of rotation. The default value is 0.
    * Y Axis Rotation–Number, in degrees of rotation. The default value is 0.
    * Z Axis Rotation–Number, in degrees of rotation. The default value is 0.| +|No Processing Required|[PassThroughProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.PassThroughProcessor)|Object|Object|Performs no processing on the file. Select this Content Processor if your content is already in a game-ready format (for example, an externally prepared DDS file) or a specialized XML format (.xml) designed for use with XNA Game Studio.| +|Sprite Font Description|[FontDescriptionProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontDescriptionProcessor)|[FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription)|[SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent)|Converts a .spritefont file specifying a font description into a font.| +|Sprite Font Texture|[FontTextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontTextureProcessor)|[TextureContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|[SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent)|A parameterized Content Processor that outputs a sprite font texture as a [SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent) object.
    Available parameters:
    * First Character–Any valid character. The space character is the default value.| +| Sprite Font Texture|[FontTextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontTextureProcessor)|[Texture2DContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.Texture2DContent)|[SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent)|Converts a specially marked 2D bitmap file (.bmp) into a font. Pixels of **Color.Magenta** are converted to **Color.Transparent**.| +| Texture|[TextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessor)|[TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|[TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|A parameterized Content Processor that outputs textures as a [TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent) object.
    Available parameters:
    * Color Key Color–Any valid [Color](xref:Microsoft.Xna.Framework.Color). [Magenta](xref:Microsoft.Xna.Framework.Color) is the default value.
    * Color Key Enabled–A Boolean value indicating if color keying is enabled. The default value is **true**.
    * Generate Mipmaps–A Boolean value indicating if mipmaps are generated. The default value is **false**.
    * Resize to Power of Two–A Boolean value indicating if a texture is resized to the next largest power of 2. The default value is **false**.
    * Texture Format–Any valid [SurfaceFormat](xref:Microsoft.Xna.Framework.Graphics.SurfaceFormat) value. Textures are either unchanged, converted to the Color format, or DXT Compressed. For more information, see [TextureProcessorOutputFormat](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessorOutputFormat).| +|Localized Sprite Font Texture|[LocalizedFontProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.LocalizedFontProcessor)|[FontDescription](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription)|[SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent)|Converts a .spritefont file specifying a font description into a font.| + +## See Also + +- [Adding Content to a Game](../../howto/Content_Pipeline/HowTo_GameContent_Add.md) +- [What Is Content?](CP_Overview.md) +- [Adding a Custom Importer](CP_AddCustomProcImp.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_StdParamProcs.md b/articles/monogame/whatis/content_pipeline/CP_StdParamProcs.md new file mode 100644 index 0000000..426e393 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_StdParamProcs.md @@ -0,0 +1,34 @@ +--- +title: What are the Parameterized Content Processors? +description: Describes how parameterized Content Processors work in MonoGame. +--- + +# Parameterized Content Processors + +Describes how parameterized Content Processors work in MonoGame. Many of the standard Content Pipeline Content Processors shipped with XNA Game Studio support parameter usage. Parameterization makes any standard or custom Content Processor more flexible and better able to meet the needs of your XNA Framework application. In addition to specifying values for standard parameters, you can easily implement parameter support for a new or an existing custom Content Processor. For more information, see [Developing with Parameterized Processors](CP_CustomParamProcs.md). + +When you select a game asset, the Properties window displays the parameters for the related Content Processor. Use the Properties window at any time to modify these parameter values. + +> **Tip** +> +> If you change the Content Processor for a game asset to a different Content Processor, all parameter values are reset to their default values. This means that if you modify the **Generate Mipmaps** parameter value for the [TextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessor) and then switch to a different Content Processor (for example, [FontTextureProcessor Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontTextureProcessor)), the parameters switch to the default values for that Content Processor. If you then switch back again, the modified values are reset to the default values of the original Content Processor. _The values do not revert to the modified values you set originally_. + +## Standard Parameterized Content Processors + +The following describes only standard Content Processors that accept parameters, the parameter types, and their default value. For more information about all standard Content Processors, see [Standard Content Importers and Content Processors](CP_StdImpsProcs.md). + +| Friendly name| Type name | Input type | Output type | Description | +|-------------------|-----------|------------|-------------|------------------------------| +| Model | [ModelProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelProcessor)| [NodeContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent)| [ModelContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelContent) |A parameterized Content Processor that outputs models as a [ModelContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelContent) object.
    Available parameters:
    *Color Key Color–Any valid [Color](xref:Microsoft.Xna.Framework.Color). [Magenta](xref:Microsoft.Xna.Framework.Color) is the default value.
    * Color Key Enabled–A Boolean value indicating if color keying is enabled. The default value is **true**.
    *Generate Mipmaps–A Boolean value indicating if mipmaps are generated. The default value is **false**.
    * Generate Tangent Frames–A Boolean value indicating if tangent frames are generated. The default value is **false**.
    *Resize Textures to Power of Two–A Boolean value indicating if a texture is resized to the next largest power of 2. The default value is **false**.
    * Scale–Any valid [float](http://msdn.microsoft.com/en-us/library/system.single.aspx) value. The default value is 1.0.
    *Swap Winding Order–A Boolean value indicating if the winding order is swapped. This is useful for models that appear to be drawn inside out. The default value is **false**.
    * Texture Format–Any valid value from [TextureProcessorOutputFormat](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessorOutputFormat). Textures are either unchanged, converted to the Color format, or Compressed using the specified Compression algorithm.
    *X Axis Rotation–Number, in degrees of rotation. The default value is 0.
    * Y Axis Rotation–Number, in degrees of rotation. The default value is 0.
    * Z Axis Rotation–Number, in degrees of rotation. The default value is 0. +| Sprite Font Texture|[FontTextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.FontTextureProcessor)|[TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|[SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent)|A parameterized Content Processor that outputs a sprite font texture as a [SpriteFontContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.SpriteFontContent) object.
    Available parameters:

    * First Character–Any valid character. The space character is the default value.| +| Texture|[TextureProcessor](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessor)|[TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|[TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent)|A parameterized Content Processor that outputs textures as a [TextureContent Class](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent) object.
    Available parameters:

    *Color Key Color–Any valid [Color](xref:Microsoft.Xna.Framework.Color). [Magenta](xref:Microsoft.Xna.Framework.Color) is the default value.
    * Color Key Enabled–A Boolean value indicating if color keying is enabled. The default value is **true**.
    *Generate Mipmaps–A Boolean value indicating if mipmaps are generated. The default value is **false**.
    * Resize to Power of Two–A Boolean value indicating if a texture is resized to the next largest power of 2. The default value is **false**.
    * Texture Format–Any valid value from [TextureProcessorOutputFormat](xref:Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessorOutputFormat). Textures are unchanged, converted to the **Color** format, or Compressed using the specified Compression algorithm.| + +## See Also + +- [Adding Content to a Game](../../howto/Content_Pipeline/HowTo_GameContent_Add.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_Tips_For_Developing.md b/articles/monogame/whatis/content_pipeline/CP_Tips_For_Developing.md new file mode 100644 index 0000000..2858b16 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_Tips_For_Developing.md @@ -0,0 +1,91 @@ +--- +title: What are Tips for Developing Custom Importers and Processors? +description: The information provided here should help when you develop Content Pipeline extensions. +--- + +# Tips for Developing Custom Importers and Processors + +The information provided should help when you develop Content Pipeline extensions. + +## Importing Basic Graphics Objects + +The following information should help you import basic graphics objects. + +- Make your coordinate system right-handed. + + From the standpoint of the observer, the positive x-axis points to the right, the positive y-axis points up, and the positive z-axis points toward you (out from the screen). + +- Create triangles that have a clockwise winding order. + + The default culling mode removes triangles that have a counterclockwise winding order. + +- Call [MeshHelper.SwapWindingOrder](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshHelper#Microsoft_Xna_Framework_Content_Pipeline_Graphics_MeshHelper_SwapWindingOrder_Microsoft_Xna_Framework_Content_Pipeline_Graphics_MeshContent_) to change the winding order of a triangle. + +- Set the scale for graphical objects to 1 unit = 1 meter. + +- Call [MeshHelper.TransformScene](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshHelper#Microsoft_Xna_Framework_Content_Pipeline_Graphics_MeshHelper_TransformScene_Microsoft_Xna_Framework_Content_Pipeline_Graphics_NodeContent_Microsoft_Xna_Framework_Matrix_) to change the scale of an object. + +## Taking Advantage of Content Pipeline Mesh Classes + +There are several properties and classes that are particularly useful when using [NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent) objects to represent a 3D scene or mesh. + +- The [NodeContent.Children](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent#Microsoft_Xna_Framework_Content_Pipeline_Graphics_NodeContent_Children) property represents hierarchical information. + +- The [NodeContent.Transform](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent#Microsoft_Xna_Framework_Content_Pipeline_Graphics_NodeContent_Transform) property contains the local transform of the 3D object. + +- The [Pipeline.Graphics.MeshContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshContent) class (a subclass of [Pipeline.Graphics.NodeContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent)) is used to represent meshes. + +The Content Pipeline provides two classes that make it easier to create and work with [Pipeline.Graphics.MeshContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshContent) objects. + +- The [Pipeline.Graphics.MeshBuilder](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshBuilder) class creates new [Pipeline.Graphics.MeshContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshContent) objects, when necessary. + +- The [Pipeline.Graphics.MeshHelper](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshHelper) class implements useful operations on existing [Pipeline.Graphics.MeshContent](xref:Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshContent) objects. + +## Debugging Custom Importers and Processors + +In a manner similar to projects that create a DLL, Content Pipeline extension projects cannot be directly run or debugged. After completing a few simple steps, however, you can debug any custom importer and processor used by your game. The following procedure details these steps. + +> **Tip** +> +> The Start External program control (located on the Debug page of a project's property pages) is unavailable in the Microsoft Visual C# Express Edition development environment. + +### To debug a custom importer or processor + +1. Load an existing MonoGame Content Pipeline extension project (later referred to as ProjCP) containing the custom importers or processors to be debugged. + +2. Create a separate test game project (later referred to as "ProjG"). + +3. In the **References** node of ProjG's nested content project, add a project-to-project reference to ProjCP. + +4. Add one or two appropriate items of test content to ProjG, and ensure they are set to use the importer or processor (in ProjCP) you wish to debug. + +5. Open the property pages for ProjCP. + +6. Click the **Debug** tab, and then select **Start external program**. + +7. Enter the path to the local version of MSBuild.exe. + + For example, C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\msbuild.exe. + +8. For the **Command line arguments** control, enter the path to ProjG's nested content project. + + If this path contains spaces, quote the entire path. + +9. Set any required breakpoints in the importer or processor code in ProjCP. + +10. Build and debug ProjCP. + +Debugging ProjCP causes MSBuild to compile your test content while running under the debugger. This enables you to hit your breakpoints in ProjCP and to step through your code. + +## See Also + +- [What Is Content?](CP_Overview.md) +- [What is the Content Pipeline?](CP_Architecture.md) +- [Extending a Standard Content Processor](../../howto/Content_Pipeline/HowTo_Extend_Processor.md) +- [Adding New Content Types](CP_Content_Advanced.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/CP_XML_Elements.md b/articles/monogame/whatis/content_pipeline/CP_XML_Elements.md new file mode 100644 index 0000000..b8bb06d --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/CP_XML_Elements.md @@ -0,0 +1,96 @@ +--- +title: What are the XML Elements for XMLImporter? +description: The base elements that are recognized by XmlImporter Class. +--- + +# XML Elements for XMLImporter + +## XML Elements + +The following base elements are recognized by [XmlImporter Class](xref:Microsoft.Xna.Framework.Content.Pipeline.XmlImporter): + +|Element|Parent|Children|Description| +|-|-|-|-| +|``|—|``|Top-level tag for XNA Content.| +|``|``|``|Marks the asset. The _Type_ attribute specifies the corresponding namespace and class of the matching data type.| +|``|``|—|When the asset contains multiple objects (as in an array), marks a single object within the group. The child elements correspond to the properties of the data type's class definition.| + +## Examples + +## Example 1: Single Object + +This example demonstrates an XML file that defines an asset that consists of a single item (not an array). + +Assume that the XML file is to define a single object of data for the class that is defined as: + +```csharp +namespace XMLTest +{ + class MyTest + { + public int elf; + public string hello; + } +} +``` + +The XML file that specifies the data that the Content Loader will read into the object would appear as: + +```xml + + + + 23 + Hello World + + +``` + +## Example 2: Multiple Objects + +This example demonstrates an XML file that defines an asset that is an array of objects. + +Assume that the XML file is to define an array of data for the class that is defined as: + +```csharp +namespace MyDataTypes +{ + public class CatData + { + public string Name; + public float Weight; + public int Lives; + } +} +``` + +The XML file that specifies the data that the Content Loader will read into the object array would appear as: + +```xml + + + + + Rhys + 17 + 9 + + + Boo + 11 + 5 + + + +``` + +## See Also + +- [Using an XML File to Specify Content](../../howto/Content_Pipeline/HowTo_UseCustomXML.md) +- [Adding Content to a Game](../../howto/Content_Pipeline/HowTo_GameContent_Add.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/content_pipeline/index.md b/articles/monogame/whatis/content_pipeline/index.md new file mode 100644 index 0000000..dcef5b0 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/index.md @@ -0,0 +1,53 @@ +--- +title: What is the Content pipeline? +description: The topics in this section describe how to add and load content such as textures, meshes, sounds, and data in your game. +requireMSLicense: true +--- + +## In This Section + +[What Is Content?](CP_Overview.md) + +Describes the purpose of the MonoGame Content Pipeline and how it helps you add art and data assets to your game. + +[Loading Content](../../howto/Content_Pipeline/HowTo_GameContent_Add.md) + +Demonstrates how to load content such as models, textures, sounds, and effects. + +[What is the Content Pipeline Architecture?](CP_Architecture.md) + +The Content Pipeline is designed to be extensible, so that it can easily support new input file formats and new types of conversion. + +[Standard Content Importers and Content Processors](CP_StdImpsProcs.md) + +Describes the standard Content Pipeline Content Importers and Content Processors of MonoGame that support various common art asset file formats. + +[What is a Custom Importer](CP_AddCustomProcImp.md) + +MonoGame provides standard importers and processors for a number of common file formats used to store such basic game assets as models, materials effects, sprites, textures, and so on. For a list of file formats supported by these standard importers and processors. + +[Parameterized Content Processors](CP_StdParamProcs.md) + +Describes how parameterized Content Processors work in MonoGame. Many of the standard Content Pipeline Content Processors shipped with MonoGame support parameter usage. + +[What are Tips for Developing Custom Importers and Processors?](CP_Tips_For_Developing.md) + +The information provided here should help when you develop Content Pipeline extensions. + +### References + +[What is MonoGame Content Pipeline Class Library?](CP_Class_Library.md) + +An overview of the MonoGame Content Pipeline Class Library reference, containing all the API calls available to the MonoGame Framework Content Framework. + +[What is the Content Pipeline Document Object Model?](CP_DOM.md) + +The MonoGame Content Document Object Model (DOM) represents the set of built-in classes that can be consumed by standard content processors. + +[What is Sprite Font XML Schema Reference?](CP_SpriteFontSchema.md) + +Describes the valid tags and values for Sprite-Font (.spritefont) XML files used by the Content Pipeline to create SpriteFont textures. + +[What are the XML Elements for XMLImporter?](CP_XML_Elements.md) + +The base elements that are recognized by XmlImporter Class. diff --git a/articles/monogame/whatis/content_pipeline/toc.yml b/articles/monogame/whatis/content_pipeline/toc.yml new file mode 100644 index 0000000..46bae55 --- /dev/null +++ b/articles/monogame/whatis/content_pipeline/toc.yml @@ -0,0 +1,2 @@ +- name: Introduction to the Content Pipeline + href: index.md diff --git a/articles/monogame/whatis/graphics/WhatIs_3DRendering.md b/articles/monogame/whatis/graphics/WhatIs_3DRendering.md new file mode 100644 index 0000000..5ad2988 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_3DRendering.md @@ -0,0 +1,68 @@ +--- +title: What is 3D Rendering? +description: The basics of the 3D rendering pipeline for MonoGame! +--- + +# 3D Pipeline Basics + +The 3D graphics pipeline uses a graphics device to load resources and render a 3D scene using an effect. + +In general, the 3D pipeline requires the following state for initialization: + +* World, view, and projection transforms to transform 3D vertices into a 2D space. +* A vertex buffer which contains the geometry to render. +* An effect that sets the render state necessary for drawing the geometry. + +As you become comfortable with these ideas, you may want to learn more about the following: manipulating vertices, creating your own effects, applying textures, or improving performance by using index buffers. + +The MonoGame Framework uses a shader-driven programmable pipeline. It requires a graphics card capable of at least Shader Model 2.0, but requirements depend on the platform being targeted. The MonoGame Framework provides a class called [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) that encapsulates most of these common operations. + +## The Graphics Device + +When you create a game with MonoGame, the framework initializes a graphics device for you. + +The [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) initializes the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) before you call [Game.Initialize](xref:Microsoft.Xna.Framework.Game.Initialize). Before you call [Initialize](xref:Microsoft.Xna.Framework.Game.Initialize), there are three ways to change the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) settings: + +1. Set the appropriate properties (e.g. [PreferredBackBufferHeight](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferHeight), [PreferredBackBufferWidth](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferredBackBufferWidth)) on the [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) in your game's constructor. + +2. Handle the ```PreparingDeviceSettings``` event on the [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager), and change the [PreparingDeviceSettingsEventArgs.GraphicsDeviceInformation.PresentationParameters](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters) member properties. + + Any changes made to the [PreparingDeviceSettingsEventArgs](xref:Microsoft.Xna.Framework.PreparingDeviceSettingsEventArgs) will override the [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) preferred settings. + +3. Handle the ```DeviceCreated``` event on the [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager), and change the [PresentationParameters](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.PresentationParameters) of the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) directly. + +When you call [Game.Initialize](xref:Microsoft.Xna.Framework.Game.Initialize), [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) creates and configures [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice). You can safely access [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) settings such as the backbuffer, depth/stencil buffer, viewport, and render states in [Initialize](xref:Microsoft.Xna.Framework.Game.Initialize). + +After you call [Game.Initialize](xref:Microsoft.Xna.Framework.Game.Initialize), changes to the [PresentationParameters](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.PresentationParameters) of the [GraphicsDevice](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice) will not take effect until you call [GraphicsDeviceManager.ApplyChanges](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.ApplyChanges). Other changes, such as render states, will take effect immediately. + +## Resources + +A resource is a collection of data stored in memory that can be accessed by the CPU or GPU. Types of resources that an application might use include render targets, vertex buffers, index buffers, and textures. + +Based on the resource management mode that was used when a resource is created, it should be reloaded when the device is reset. For more information, see [Loading Resources](../../howto/Content_Pipeline/HowTo_LoadContentLibrary.md). + +### Vertex and Index Buffers + +A vertex buffer contains a list of 3D vertices to be streamed to the graphics device. Each vertex in a vertex buffer may contain data about not only the 3D coordinate of the vertex, but also other information describing the vertex, such as the vertex normal, color, or texture coordinate. The MonoGame Framework contains several classes to describe common vertex declaration types, such as [VertexPositionColor](xref:Microsoft.Xna.Framework.Graphics.VertexPositionColor), [VertexPositionColorTexture](xref:Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture), [VertexPositionNormalTexture](xref:Microsoft.Xna.Framework.Graphics.VertexPositionNormalTexture), and [VertexPositionTexture](xref:Microsoft.Xna.Framework.Graphics.VertexPositionTexture). Use the [VertexElement](xref:Microsoft.Xna.Framework.Graphics.VertexElement) class to compose custom vertex types. + +Vertex buffers contain indexed or non-indexed vertex data. + +If a vertex buffer is not indexed, all of the vertices are placed in the vertex buffer in the order they are to be rendered. Because 3D line lists or triangle lists often reference the same vertices multiple times, this can result in a large amount of redundant data. + +Index buffers allow you to list each vertex only once in the vertex buffer. An index buffer is a list of indices into the vertex buffer, given in the order that you want the vertices to render. + +To render a non-indexed vertex buffer, call the [GraphicsDevice.DrawPrimitives](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawPrimitives_Microsoft_Xna_Framework_Graphics_PrimitiveType_System_Int32_System_Int32_) or [GraphicsDevice.DrawUserPrimitives](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawUserPrimitives__1_Microsoft_Xna_Framework_Graphics_PrimitiveType___0___System_Int32_System_Int32_) Methods. + +To render an indexed buffer, call the [GraphicsDevice.DrawIndexedPrimitives](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawIndexedPrimitives_Microsoft_Xna_Framework_Graphics_PrimitiveType_System_Int32_System_Int32_System_Int32_) or [GraphicsDevice.DrawUserIndexedPrimitives](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_DrawUserIndexedPrimitives__1_Microsoft_Xna_Framework_Graphics_PrimitiveType___0___System_Int32_System_Int32_System_Int16___System_Int32_System_Int32_) Methods. + +### Textures + +A texture resource is a structured collection of texture data. The data in a texture resource is made up of one or more subresources that are organized into arrays and mipmap chains. Textures are filtered by a texture sampler as they are read. The type of texture influences how the texture is filtered. + +You can apply textures by using the [Texture](xref:Microsoft.Xna.Framework.Graphics.BasicEffect.Texture) property of the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) class, or choose to write your own effect methods to apply textures. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_Antialiasing.md b/articles/monogame/whatis/graphics/WhatIs_Antialiasing.md new file mode 100644 index 0000000..0e5d5d9 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_Antialiasing.md @@ -0,0 +1,22 @@ +--- +title: What is Antialiasing? +description: The definition of Antialsing for MonoGame! +--- + +# What Is Antialiasing? + +Antialiasing is a technique for softening or blurring sharp edges so they appear less jagged when rendered. + +Antialiasing is accomplished by multisampling each pixel at multiple pixel locations and combining the samples to generate a final pixel color. Increasing the number of samples per pixel increases the amount of antialiasing which generates a smoother edge. 4x multisampling requires four samples per pixel and 2x multisampling requires two sampler per pixel. Use the [MultiSampleCount](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters.MultiSampleCount) property of the [PresentationParameters](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters) class to set the number of samples for the back buffer. + +Set the [PreferMultiSampling](xref:Microsoft.Xna.Framework.GraphicsDeviceManager.PreferMultiSampling) property on the [GraphicsDeviceManager](xref:Microsoft.Xna.Framework.GraphicsDeviceManager) class to **true** to enable multisampling for the back buffer. This will be ignored if the hardware does not support multisampling. + +## See Also + +[Enabling Anti-aliasing (Multi-sampling)](../../howto/graphics/HowTo_Enable_Anti_Aliasing.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_BackBuffer.md b/articles/monogame/whatis/graphics/WhatIs_BackBuffer.md new file mode 100644 index 0000000..56eebf1 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_BackBuffer.md @@ -0,0 +1,26 @@ +--- +title: What Is a Back Buffer? +description: The definition of a Back Buffer for MonoGame! +--- + +# What Is a Back Buffer? + +A back buffer is a render target whose contents will be sent to the device when [GraphicsDevice.Present](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Present) is called. + +The graphics pipeline renders to a render target. The particular render target that the device presents to the display is called the back buffer. Use the [BackBufferWidth](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters.BackBufferWidth) and [BackBufferHeight](xref:Microsoft.Xna.Framework.Graphics.PresentationParameters.BackBufferHeight) properties to get the back buffer dimensions. Render directly to the back buffer or to a render target by configuring the device using [GraphicsDevice.SetRenderTarget](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_SetRenderTarget_Microsoft_Xna_Framework_Graphics_RenderTarget2D_) and [GraphicsDevice.SetRenderTargets](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_SetRenderTargets_Microsoft_Xna_Framework_Graphics_RenderTargetBinding___). + +For Windows, the back buffer is created to match the dimensions of the [ClientBounds](xref:Microsoft.Xna.Framework.GameWindow.ClientBounds) by default. For Xbox 360, the back buffer is created with the dimensions that have been specified by the user. When going into full-screen mode on Windows, it is often desirable to set the back buffer dimensions to match the [DisplayMode](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.DisplayMode) dimensions so that the game ("display") resolution does not change when it goes into the full-screen mode. + +The back buffer created for Xbox 360 is not necessarily the same size as the final resolution on a television connected for display. The Xbox 360 automatically scales output to the television resolution selected by the user in the System Blade. If the aspect ratio of the back buffer is different from the aspect ratio of the television display mode, the Xbox 360 will automatically add black bars (also called letterboxing) if the user's display is not widescreen. + +In addition, if you request a back-buffer resolution that is not supported by the output device, the MonoGame framework automatically selects the highest resolution supported by the output device. For example, if you create a back-buffer with a resolution of 1920x1080 (for example, 1080p or 1080i) and display it on a device with 480i resolution, the back-buffer is resized to 480i automatically. + +## See Also + +[Viewport](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Viewport) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_BlendState.md b/articles/monogame/whatis/graphics/WhatIs_BlendState.md new file mode 100644 index 0000000..3e86f2e --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_BlendState.md @@ -0,0 +1,20 @@ +--- +title: What Is Blend State? +description: The definition for the Blend State for MonoGame! +--- + +# What Is Blend State? + +Blend state controls how color and alpha values are blended when combining rendered data with existing render target data. + +The blend state class, [BlendState](xref:Microsoft.Xna.Framework.Graphics.BlendState), contains state that controls how colors are blended. Each time you render, the pixel data you generate (call it source data) is stored in a render target. The render target might be empty or it might already contain data (call it destination data). Blending occurs each time you combine source and destination data. + +You have a lot of control over how you blend the source and the destination data. For example, you can choose to overwrite the destination with the source data by setting [BlendState.Opaque](xref:Microsoft.Xna.Framework.Graphics.BlendState) or combine the data by adding them together using [BlendState.Additive](xref:Microsoft.Xna.Framework.Graphics.BlendState). You can blend only the color data or the alpha data, or both, by setting up the blending functions [ColorBlendFunction](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorBlendFunction) and [AlphaBlendFunction](xref:Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlendFunction). You can even limit your blending operation to one or more colors (or channels) using [ColorWriteChannels](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorWriteChannels). + +For an example that creates and uses a state object, see [Creating a State Object](../../howto/graphics/HowTo_Create_a_StateObject.md). + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_ColorBlending.md b/articles/monogame/whatis/graphics/WhatIs_ColorBlending.md new file mode 100644 index 0000000..9c1ab16 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_ColorBlending.md @@ -0,0 +1,66 @@ +--- +title: What Is Color Blending? +description: The definition for Color Blending for MonoGame! +--- + +# What Is Color Blending? + +Color blending mixes two colors together to produce a third color. + +The first color is called the source color which is the new color being added. The second color is called the destination color which is the color that already exists (in a render target, for example). Each color has a separate blend factor that determines how much of each color is combined into the final product. Once the source and destination colors have been multiplied by their blend factors, the results are combined according to the specified blend function. The normal blend function is simple addition. + +The blend formula looks like this: + +```text +(source * sourceBlendFactor) blendFunction (destination*destinationBlendFactor) +``` + +The source blend factor is specified by the [ColorSourceBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorSourceBlend) property, and the destination blend factor is specified by the [ColorDestinationBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorDestinationBlend) property. The [ColorBlendFunction](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorBlendFunction) property specifies the blend function to use, normally [BlendFunction.Add](/api/Microsoft.Xna.Framework.Graphics.BlendFunction.html). In that case the formula reduces to this: + +```text +(source * sourceBlendFactor) + (destination * destinationBlendFactor) +``` + +When no blending is done, a source pixel overwrites a destination pixel. When blending, you can create a lot of special effects using the blending properties: + +* Blend type +* Blend settings + +## Alpha Blending + +(_source_ × [Blend.SourceAlpha](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) \+ (_destination_ × [Blend.InvSourceAlpha](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) + +## Additive Blending + +(_source_ × [Blend.One](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) \+ (_destination_ × [Blend.One](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) + +## Multiplicative Blending + +(_source_ × [Blend.Zero](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) \+ (_destination_ × [Blend.SourceColor](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) + +## 2X Multiplicative Blending + +(_source_ × [Blend.DestinationColor](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) \+ (_destination_ × [Blend.SourceColor](/api/Microsoft.Xna.Framework.Graphics.Blend.html)) + +**Figure 1.  This picture illustrates four common blend modes. From left to right: Alpha blending, Additive blending, Multiplicative blending, and 2X Multiplicative blending. The top image in each column is the source image and below, it's effect when added to the destination.** + +![This picture illustrates four common blend modes](../images/blends.jpg) + +Alpha blending uses the alpha channel of the source color to create a transparency effect so that the destination color appears through the source color. For example, if you clear your backbuffer to [Color.Gray](/api/Microsoft.Xna.Framework.Color.html), it will be colored (0.5,0.5,0.5,1). If you then take a white color with a partial alpha value (1,1,1,0.4), the result will be 60 percent of the destination color and 40 percent of the source: (0.5 x 0.6) + (1 x 0.4). The resulting color will be (0.7,0.7,0.7, 1). The alpha values are multiplied as well - (.6 x 1) + .4 gives us an alpha value of 1. + +When drawing a sprite using the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) class, choose [BlendState.AlphaBlend](/api/Microsoft.Xna.Framework.Graphics.BlendState.html) to configure alpha blending. + +By default, the alpha channel is blended along with the red, green, and blue channels using the [ColorSourceBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorSourceBlend) and [ColorDestinationBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState.ColorDestinationBlend) properties. You can choose to customize the blending for just the alpha channel by using the [AlphaSourceBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState.AlphaSourceBlend) and [AlphaDestinationBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState.AlphaDestinationBlend) properties. + +## See Also + +### Concepts + +[What Is a Sprite?](WhatIs_Sprite.md) +[3D Pipeline Basics](WhatIs_3DRendering.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_ConfigurableEffect.md b/articles/monogame/whatis/graphics/WhatIs_ConfigurableEffect.md new file mode 100644 index 0000000..389aaaf --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_ConfigurableEffect.md @@ -0,0 +1,65 @@ +--- +title: What Is a Configurable Effect? +description: The definition for a Configurable Effect for MonoGame! +--- + +# What Is a Configurable Effect? + +A configurable effect is an optimized rendering effect designed for use with MonoGame. A configurable effect is created using a built-in object with options for user configuration. + +An effect initializes the graphics pipeline for performing transforms, lighting, applying textures, and adding per-pixel visual effects such as a glow or a lens flare. Under the covers, an effect implements at least one shader for processing vertices and at least one shader for processing pixels. + +During rendering, the graphics pipeline transforms 3D geometry to a 2D surface, giving you the option of adding lighting, texturing and many other per-vertex or per-pixel visual effects. An effect initializes the pipeline to render 3D geometry using vertex and pixel shaders, although you can also render a 2D sprite with an effect. + +Although more advanced progammable effects are available on Windows and other platfroms. There are several built-in configurable effects which have been designed to run efficiently on mobile GPU hardware, and which are appropriate to the Reach [profile](../WhatIs_Profile.md) used for Windows Phone games. + +Use one of the following configurable effects to implement these rendering effects: + +* [Basic Lighting and Fog](#basic-lighting-and-fog) +* [Character Animation](#character-animation) +* [More Sophisticated Lighting with a Light Map](#more-sophisticated-lighting-with-a-light-map) +* [Billboards and Imposters](#billboards-and-imposters) +* [Lighting Highlights Using an Environment Map](#lighting-highlights-using-an-environment-map) + +## Basic Lighting and Fog + +Use the [BasicEffect](xref:Microsoft.Xna.Framework.Graphics.BasicEffect) configurable effect to implement general purpose functionality, including the following: transformations; lighting with three directional lights; material colors using ambient, diffuse, and specular properties; a single texture; and fog. To improve speed, fog calculations are based on depth instead of distance from the camera. When you choose a basic effect, you can improve the performance of your game if you don't use any fog or if you only use one of the three available directional lights. For an example, see [Creating a Basic Effect](../../howto/graphics/HowTo_Create_a_BasicEffect.md). + +## Character Animation + +Use the [SkinnedEffect](xref:Microsoft.Xna.Framework.Graphics.SkinnedEffect) configurable effect to animate a character. This effect uses bones and weights to transform a mesh (an object is made up of several meshes). Simply set up a set of bones for a model when you create content, and then transform the bones during the render loop. You can also use this class for hardware instancing by setting **WeightsPerVertex** to one, and replicating the geometry data with an additional bone index channel. This is similar to the way the shader instancing technique works in the instancing sample. + +## More Sophisticated Lighting with a Light Map + +Use the [DualTextureEffect](xref:Microsoft.Xna.Framework.Graphics.DualTextureEffect) configurable effect with a prebaked radiosity lightmap to add more sophisticated lighting to a scene. This effect uses two textures, the base texture with the texture detail and an overlay texture with the prebaked lighting. + +The two textures are combined using a fixed modulate2X blend formula as shown here: + +```csharp + result.rgb = x.rgb * y.rgb * 2; + result.a = x.a * y.a; +``` + +## Billboards and Imposters + +Use the [AlphaTestEffect](xref:Microsoft.Xna.Framework.Graphics.AlphaTestEffect) configurable effect to use alpha data to test whether to draw a pixel. The effect uses a **CompareFunction** to compare the alpha value for a pixel against the **ReferenceAlpha** value to determine whether to draw the pixel. This functionality is used for drawing a billboard (a 2D sprite that faces the camera) and an imposter (a 2D sprite that is integrated into a larger scene). + +## Lighting Highlights Using an Environment Map + +Use the [EnvironmentMapEffect](xref:Microsoft.Xna.Framework.Graphics.EnvironmentMapEffect) configurable effect to generate fast, specular highlights that add shininess to an object. The effect uses two textures, a base texture with the texture detail and a cubemap whose six sides reflect the environment onto the object. Use **EnvironmentMapAmount** to control the amount of the environment map to add to the object. Also, use **FresnelFactor** to control how much the edge of an object reflects specular lighting. + +Pseudo code for the lighting calculations looks similar to this: + +```csharp + viewAngle = dot(eyeToVertexVector, vertexNormal); + fresnel = saturate(pow(1 – abs(viewAngle), FresnelFactor); + amount = fresnel * EnvironmentMapAmount; + result.rgb = lerp(diffuseTexture.rgb, cubeTexture.rgb, amount); + result.rgb += cubeTexture.a * EnvironmentMapSpecular +``` + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_DepthBuffer.md b/articles/monogame/whatis/graphics/WhatIs_DepthBuffer.md new file mode 100644 index 0000000..0cf30f0 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_DepthBuffer.md @@ -0,0 +1,24 @@ +--- +title: What Is a Depth Buffer? +description: The definition for a Depth Buffer for MonoGame! +--- + +# What Is a Depth Buffer? + +A depth buffer contains per-pixel floating-point data for the z depth of each pixel rendered. A depth buffer may also contain stencil data which can be used to do more complex rendering such as simple shadows or outlines. + +When a pixel is rendered, color data as well as depth data can be stored. If a pixel is rendered a second time - such as when two objects overlap - depth testing determines which pixel is closer to the camera. The depth function determines what to do with the test result. For example, if [CompareFunction.LessEqual](/api/Microsoft.Xna.Framework.Graphics.CompareFunction.html) is the current depth function, if the current pixel depth is less than or equal to the previous pixel depth, the current pixel depth is written to the depth buffer. Values that fail the depth test are discarded. + +The depth of a pixel, which ranges between 0.0 and 1.0, is determined based on the view and projection matrices. A pixel that touches the near plane has depth 0, a pixel that touches the far plane has depth 1. As each object in the scene is rendered, normally the pixels that are closest to the camera are kept, as those objects block the view of the objects behind them. + +A depth buffer may also contain stencil bits - for this reason it's often called a _depth-stencil buffer_. The depth format describes the data format of the depth buffer. The depth buffer is always 32 bits, but those bits can be arranged in different ways, similar to how texture formats can vary. A common depth format is [DepthFormat.Depth24Stencil8](/api/Microsoft.Xna.Framework.Graphics.DepthFormat.html), where 24 bits are used for the depth data and 8 bits are used for the stencil data. [DepthFormat.Depth24Stencil8Single](/api/Microsoft.Xna.Framework.Graphics.DepthFormat.html) is a more unusual format where the 24 bits for the depth buffer are arranged as a floating point value. Use [DepthFormat.None](/api/Microsoft.Xna.Framework.Graphics.DepthFormat.html) if you don't want to create a depth buffer. + +Use [DepthStencilState.DepthBufferEnable](xref:Microsoft.Xna.Framework.Graphics.DepthStencilState.DepthBufferEnable) to enable or disable depth buffering. Use the [DepthStencilState.DepthBufferFunction](xref:Microsoft.Xna.Framework.Graphics.DepthStencilState.DepthBufferFunction) to change the comparison function used for the depth test. Clear the depth buffer by passing [ClearOptions.DepthBuffer](/api/Microsoft.Xna.Framework.Graphics.ClearOptions.html) to [GraphicsDevice.Clear](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_Clear_Microsoft_Xna_Framework_Color_). + +In MonoGame there is no **DepthStencilBuffer** type. The runtime automatically creates a depth buffer when a render target is created, and you specify the format for the depth buffer in a render target's constructor along with the surface format. This prevents a render target from being created without a matching depth buffer. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_DepthStencilState.md b/articles/monogame/whatis/graphics/WhatIs_DepthStencilState.md new file mode 100644 index 0000000..c6039c0 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_DepthStencilState.md @@ -0,0 +1,20 @@ +--- +title: What Is Depth Stencil State? +description: The definition for the Depth Stencil State for MonoGame! +--- + +# What Is Depth Stencil State? + +Depth stencil state controls how the depth buffer and the stencil buffer are used. + +The depth buffer stores floating-point depth or z data for each pixel while the stencil buffer stores integer data for each pixel. The depth-stencil state class, [DepthStencilState](xref:Microsoft.Xna.Framework.Graphics.DepthStencilState), contains state that controls how depth and stencil data impacts rendering. + +During rendering, the z position (or depth) of each pixel is stored in the depth buffer. When rendering pixels more than once -- such as when objects overlap -- depth data is compared between the current pixel and the previous pixel to determine which pixel is closer to the camera. When a pixel passes the depth test, the pixel color is written to a render target and the pixel depth is written to the depth buffer. For more information about a depth buffer, see [What Is a Depth Buffer?](WhatIs_DepthBuffer.md). + +A depth buffer may also contain stencil data, which is why a depth buffer is often called a depth-stencil buffer. Use a stencil function to compare a reference stencil value -- a global value you set -- to the per-pixel value in the stencil buffer to mask which pixels get saved and which are discarded. For more information about a stencil buffer, see [What Is a Stencil Buffer?](WhatIs_StencilBuffer.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_ModelBone.md b/articles/monogame/whatis/graphics/WhatIs_ModelBone.md new file mode 100644 index 0000000..c6bb47a --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_ModelBone.md @@ -0,0 +1,20 @@ +--- +title: What Is a Model Bone? +description: The definition for a Model Bone for MonoGame! +--- + +# What Is a Model Bone? + +A model bone is a matrix that represents the position of a mesh as it relates to other meshes in a 3D model. + +![The structure of a ModelMesh](../images/Model-ModelMesh.png) + +A complex computer-generated object, often called a model, is made up of many vertices and materials organized into a set of meshes. In the XNA Framework, a model is represented by the [Model](xref:Microsoft.Xna.Framework.Graphics.Model) class. A model contains one or more meshes, each of which is represented by a [ModelMesh](xref:Microsoft.Xna.Framework.Graphics.ModelMesh) class. Each mesh is associated with one bone represented by the [ModelBone](xref:Microsoft.Xna.Framework.Graphics.ModelBone) class. + +The bone structure is set up to be hierarchical to make controlling each mesh (and therefore the entire model) easier. At the top of the hierarchy, the model has a [Root](xref:Microsoft.Xna.Framework.Graphics.Model.Root) bone to specify the overall position and orientation of the model. Each [ModelMesh](xref:Microsoft.Xna.Framework.Graphics.ModelMesh) object contains a [ParentBone](xref:Microsoft.Xna.Framework.Graphics.ModelMesh.ParentBone) and one or more [ModelBone](xref:Microsoft.Xna.Framework.Graphics.ModelBone). You can transform the entire model using the parent bone as well as transform each individual mesh with its bone. To animate one or more bones, update the bone transforms during the render loop by calling [Model.CopyAbsoluteBoneTransformsTo Method](/api/Microsoft.Xna.Framework.Graphics.Model.html#Microsoft_Xna_Framework_Graphics_Model_CopyAbsoluteBoneTransformsTo_Microsoft_Xna_Framework_Matrix___), which iterates the individual bone transforms to make them relative to the parent bone. To draw an entire model, loop through a mesh drawing each sub mesh. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_Rasterizer.md b/articles/monogame/whatis/graphics/WhatIs_Rasterizer.md new file mode 100644 index 0000000..a1007c9 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_Rasterizer.md @@ -0,0 +1,36 @@ +--- +title: What Is Rasterizer State? +description: The definition for a Rasterizer for MonoGame! +--- + +# What Is Rasterizer State? + +Rasterizer state determines how to render 3D data such as position, color, and texture onto a 2D surface. + +Rasterization takes a 3D scene containing polygons (which are represented by triangles and vertices) and renders the scene onto a 2D surface. This requires mapping or transforming the 3D vertices into 2D vertices using the world, view, and projection transforms to calculate the final vertex positions in the viewing frustum. To reduce the amount of geometry that needs to be rasterized, the rasterizer clips geometry so that only the parts of a polygon that are visible get processed. The resulting list of transformed vertices is then scan-converted to determine how to fill pixel positions between vertices. Scissor testing takes a list of user-supplied rectangles to further limit the areas you may want rasterized. + +Create a rasterizer state object using the [RasterizerState](xref:Microsoft.Xna.Framework.Graphics.RasterizerState) class. Set the rasterizer state to the graphics device using the [RasterizerState](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.RasterizerState) property. + +This is the default state for rasterization: + +* Render triangles with clockwise winding order. +* Fill primitives so they are solid. +* Turn off scissor testing. +* Enable multisampling. +* Avoid using either depth bias or sloped scaled depth bias. + +These are the corresponding API states: + +* Set [CullMode](xref:Microsoft.Xna.Framework.Graphics.RasterizerState.CullMode) to **CullMode.CullCounterClockwiseFace**. +* Set [FillMode](xref:Microsoft.Xna.Framework.Graphics.RasterizerState.FillMode) to **FillMode.Solid**. +* Set [ScissorTestEnable](xref:Microsoft.Xna.Framework.Graphics.RasterizerState.ScissorTestEnable) to **false**. +* Set [MultiSampleAntiAlias](xref:Microsoft.Xna.Framework.Graphics.RasterizerState.MultiSampleAntiAlias) to **true**. +* Set [DepthBias](xref:Microsoft.Xna.Framework.Graphics.RasterizerState.DepthBias) and [SlopeScaleDepthBias](xref:Microsoft.Xna.Framework.Graphics.RasterizerState.SlopeScaleDepthBias) to 0. + +Built-in state objects make it easy to create objects with the most common rasterizer state settings. **CullNone**, **CullClockwise**, and **CullCounterClockwise** are the most common settings. For an example of creating a state object, see [Creating a State Object](../../howto/graphics/HowTo_Create_a_StateObject.md). + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_Render_Target.md b/articles/monogame/whatis/graphics/WhatIs_Render_Target.md new file mode 100644 index 0000000..53ef367 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_Render_Target.md @@ -0,0 +1,30 @@ +--- +title: What Is a Render Target? +description: The definition for a Render Target for MonoGame! +--- + +# What Is a Render Target? + +A render target is a memory buffer for rendering pixels. One common use for a render target is offscreen rendering. + +The graphics pipeline has a default render target called the back buffer, which is a portion of video memory that contains the next frame to be drawn. If your program does not create a render target, and you render to the screen, you are using the back buffer by default. Use the [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) class to create additional render targets. A common scenario is to render to one or more offscreen render targets and assemble them in the back buffer to produce the final frame. + +The [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) class derives from the [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) class because a render target contains a 2D texture. + +- To draw a render target like you would draw a texture, use the render target object directly. That is, pass a [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) object to any method that takes a [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) object. + +- To read render target data back to the CPU, call the [Texture2D.GetData Method](/api/Microsoft.Xna.Framework.Graphics.Texture2D.html#Microsoft_Xna_Framework_Graphics_Texture2D_GetData__1___0___). For more information about using a render target, see [Creating a Render Target](../../howto/graphics/HowTo_Create_a_RenderTarget.md). + +To use a render target, create a [RenderTarget2D](xref:Microsoft.Xna.Framework.Graphics.RenderTarget2D) object with the width, height, and other options you prefer. Call [GraphicsDevice.SetRenderTarget](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_SetRenderTarget_Microsoft_Xna_Framework_Graphics_RenderTarget2D_) to make your render target the current render target. Any subsequent **Draw** calls you make will draw into your render target rather than the back buffer. When you are finished rendering, call [GraphicsDevice.SetRenderTarget](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_SetRenderTarget_Microsoft_Xna_Framework_Graphics_RenderTarget2D_) and pass it null to set the device to render to the back buffer again. + +There are other considerations for choosing width and height when you create a render target. For example, you should choose the width and height of the back buffer to match the size of your game window (although Windows Phone scales the final result to match the user's screen). This prevents any resizing when the back buffer is copied to the screen. However, an offscreen render target does not need to have the same width and height as the back buffer. The final image can be rendered in several small render targets and then reassembled in a larger render target. + +A render target has a surface format, which describes how many bits are allocated to each pixel, and how they are divided between red, green, blue, and alpha. For example, [SurfaceFormat.Bgr565](https://monogame.net/api/Microsoft.Xna.Framework.Graphics.SurfaceFormat.html) allocates 16 bits per pixel; 5 bits for blue and red and 6 bits for green. + +A render target works in cooperation with a depth-stencil buffer. When creating a render target, the depth format for the depth-stencil buffer is specified as one of the parameters to the render target constructor. Anytime you set a new render target to the device, the matching depth buffer is also set to the device. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_Sampler.md b/articles/monogame/whatis/graphics/WhatIs_Sampler.md new file mode 100644 index 0000000..666cf73 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_Sampler.md @@ -0,0 +1,38 @@ +--- +title: What Is Sampler State? +description: The definition for a Sampler State for MonoGame! +--- + +# What Is Sampler State? + +Sampler state determines how texture data is sampled using texture addressing modes, filtering, and level of detail. + +Sampling is done each time a texture pixel, or texel, is read from a texture. A texture contains an array of texels, or texture pixels. The position of each texel is denoted by (u,v), where _u_ is the width and _v_ is the height, and is mapped between 0 and 1 based on the texture width and height. The resulting texture coordinates are used to address a texel when sampling a texture. + +When texture coordinates are below 0 or above 1, the texture address mode defines how the texture coordinate addresses a texel location. For example, when using [TextureAddressMode.Clamp](https://monogame.net/api/Microsoft.Xna.Framework.Graphics.TextureAddressMode.html), any coordinate outside the 0-1 range is clamped to a maximum value of 1, and minimum value of 0 before sampling. + +If the texture is too large or too small for the polygon, the texture is filtered to fit the space. A magnification filter enlarges a texture, a minification filter reduces the texture to fit into a smaller area. Texture magnification repeats the sample texel for one or more addresses which yields a blurrier image. Texture minification is more complicated because it requires combining more than one texel value into a single value. This can cause aliasing or jagged edges depending on the texture data. The most popular approach for minification is to use a mipmap. A mipmap is a multi-level texture. The size of each level is a power-of-two smaller than the previous level down to a 1x1 texture. When minification is used, a game chooses the mipmap level closest to the size that is needed at render time. + +Use the [SamplerState](xref:Microsoft.Xna.Framework.Graphics.SamplerState) class to create a sampler state object. Set the sampler state to the graphics device using the [GraphicsDevice.SamplerStates Property](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.SamplerStates) property. + +This is the default state for sampling: + +* Use linear filtering. +* Wrap texture addresses on boundaries. +* Set the maximum anisotropy value to 4. +* Do not use mip maps or LOD bias. + +These are the corresponding API states: + +* Set [Filter](xref:Microsoft.Xna.Framework.Graphics.SamplerState.Filter) to **TextureFilter.Linear**. +* Set [AddressU](xref:Microsoft.Xna.Framework.Graphics.SamplerState.AddressU), [AddressV](xref:Microsoft.Xna.Framework.Graphics.SamplerState.AddressV), and [AddressW](xref:Microsoft.Xna.Framework.Graphics.SamplerState.AddressW) to **TextureAddressMode.Wrap**. +* Set [MaxAnisotropy](xref:Microsoft.Xna.Framework.Graphics.SamplerState.MaxAnisotropy) to 4. +* Set [MaxMipLevel](xref:Microsoft.Xna.Framework.Graphics.SamplerState.MaxMipLevel) and [MipMapLevelOfDetailBias](xref:Microsoft.Xna.Framework.Graphics.SamplerState.MipMapLevelOfDetailBias) to 0. + +Built-in state objects make it easy to create objects with the most common sampler state settings. The most common settings are **LinearClamp**, **LinearWrap**, **PointClamp**, **PointWrap**, **AnisotropicClamp**, and **AnisotropicWrap**. For an example of creating a state object, see [Creating a State Object](../../howto/graphics/HowTo_Create_a_StateObject.md). + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_Sprite.md b/articles/monogame/whatis/graphics/WhatIs_Sprite.md new file mode 100644 index 0000000..1034b10 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_Sprite.md @@ -0,0 +1,104 @@ +--- +title: What Is a Sprite? +description: The definition for Sprites in MonoGame! +--- + +# What Is a Sprite? + +Sprites are 2D bitmaps that are drawn directly to a render target without using the pipeline for transformations, lighting or effects. Sprites are commonly used to display information such as health bars, number of lives, or text such as scores. Some games, especially older games, are composed entirely of sprites. + +* [Overview](#overview) +* [Sprite Origin](#sprite-origin) +* [Sprite Depth](#sprite-depth) +* [Sampling Textures](#sampling-textures) +* [Sprite Scaling](#sprite-scaling) +* [Sprite Transformation Matrices](#sprite-transformation-matrices) +* [Sprite Fonts](#sprite-fonts) +* [Sprite Batching](#sprite-batching) + +## Overview + +Sprites are positioned on the screen by coordinates. The width and height of the screen is the same as the back buffer. The x-axis represents the screen width and the y-axis represents the screen height. The y-axis is measured from the top of the screen and increases as you move _down_ the screen, and the x-axis is measured from left to right. For example, when the graphics back buffer is 800×600, 0,0 is the upper left of the screen, and 800,600 is the lower right of the screen. + +To draw a sprite, create a [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object, initialize it by calling [Begin](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__), and then call [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) for each sprite. The bitmap data for a sprite is taken from a [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) object. The texture may contain alpha channel information to make part of the texture transparent or semi-transparent. You can tint, rotate, or scale sprites by using [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_). This method also gives you the option of drawing only part of the texture on the screen. After you draw a sprite, call [End](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) before calling [Present](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Present). + +## Sprite Origin + +When you draw a sprite, the sprite _origin_ is an important concept. The origin is a specific point on the sprite, which is by default the upper-left corner of the sprite, or (0,0). [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) draws the origin of the sprite at the screen location you specify. For example, if you draw a 50×50 pixel sprite at location (400,200) without specifying an origin, the upper left of the sprite will be on pixel (400,200). If you use the center of the 50×50 sprite as the origin (25,25), to draw the sprite in the same position you must add the origin coordinates to the position. In this case, the position is (425,225) and the origin is (25,25). + +When rotating a sprite, the method uses the origin as the center of the rotation. In these cases, it is common to use the center of the sprite as the origin when calculating where to draw the sprite on the screen. + +## Sprite Depth + +Sprites also have a concept of _depth_ which is a floating-point number between 0 and 1. Sprites drawn at a depth of 0 are drawn in front of sprites which have a depth of greater than 0; sprites drawn at a depth of 1 are covered by sprites drawn at a depth less than 1. + +## Sampling Textures + +A sprite is based on a [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) object—in other words, a bitmap. Use [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) to draw the entire texture or a portion of the texture. To draw a portion of the texture, use the **sourceRectangle** parameter to specify which _texels_, or texture pixel, to draw. A 32×32 texture has 1024 texels, specified as x and y values similar to how screen coordinates are specified. Specifying a **sourceRectangle** of (0, 0, 16, 16) would select the upper-left quadrant of a 32×32 texture. + +## Sprite Scaling + +[Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) provides three options for scaling a sprite: using a uniform scaling parameter, a nonuniform scaling parameter, or a source and destination rectangle. The uniform scaling parameter is a floating-point number that multiplies the sprite size through both the x- and y-axes. This will shrink or expand the sprite along each axis equally, maintaining the original ratio between the sprite width and height. + +To scale the x- and y-axes independently, [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) accepts a [Vector2](xref:Microsoft.Xna.Framework.Vector2) value as a scalar. This [Vector2](xref:Microsoft.Xna.Framework.Vector2) specifies nonuniform scaling: x- and y-axes are scaled independently according to the ```X``` and ```Y``` fields of the [Vector2](xref:Microsoft.Xna.Framework.Vector2). + +[Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) also accepts a source and destination rectangle. The destination rectangle is specified in screen coordinates, while the source rectangle is specified in texels. [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) takes the pixels on the texture specified in **sourceRectangle** and scales them independently along the x- and y-axes until they fit the screen coordinates specified by **destinationRectangle**. + +## Sprite Transformation Matrices + +You can also specify a transformation matrix that the batch can apply to each sprite before drawing. The transformation matrix can be any combination of translation, rotation, or scaling matrices multiplied together into a single matrix. This matrix is combined with the sprite position, rotation, scaling, and depth parameters supplied to [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_). Because the matrix also applies to depth, any z-coordinate transformation that makes the sprite depth greater than 1.0 or less than 0.0 will cause the sprite to disappear. + +See [Rotating a Group of Sprites](../../howto/graphics/HowTo_Rotate_Sprite_Group.md) for an example of matrix rotation and [Scaling Sprites Based On Screen Size](../../howto/graphics/HowTo_Scale_Sprites_Matrix.md) for an example of matrix scaling. + +## Sprite Fonts + +Use a [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) to draw text. The [DrawString](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_DrawString_Microsoft_Xna_Framework_Graphics_SpriteFont_System_String_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) method will draw text on screen with position, color, rotation, origin, and scaling. [DrawString](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_DrawString_Microsoft_Xna_Framework_Graphics_SpriteFont_System_String_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_) also requires a special type of texture encapsulated by the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) class. A [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) is created by the content pipeline when you add a Sprite Font file to your project. The sprite font file has information such as the name and point size of the font, and which Unicode characters to include in the [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) texture. At run time, a [SpriteFont](xref:Microsoft.Xna.Framework.Graphics.SpriteFont) is loaded with [ContentManager.Load](/api/Microsoft.Xna.Framework.Content.ContentManager.html#Microsoft_Xna_Framework_Content_ContentManager_Load__1_System_String_) just like a [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D) object. + +See [Sprite Font XML Schema Reference](../content_pipeline/CP_SpriteFontSchema.md) for a list of Sprite Font tags. You can use the content pipeline to determine your character regions automatically. For more information, see [How to: Extend the Font Description Processor to Support Additional Characters](../../howto/content_pipeline/HowTo_Extend_Processor.md). + +The following redistributable fonts are installed by XNA Game Studio. For information about redistribution rights, see the text in the end user license agreement. + +* Andyb.ttf +* JingJing.ttf +* Kooten.ttf +* Linds.ttf +* Miramo.ttf +* Miramob.ttf +* Moire-Bold.ttf +* Moire-ExtraBold.ttf +* Moire-Light.ttf +* Moire-Regular.ttf +* MotorwerkOblique.ttf +* NGO_____.ttf +* NGOB____.ttf +* OcraExt.ttf +* Peric.ttf +* Pericl.ttf +* Pesca.ttf +* Pescab.ttf +* QuartMS.ttf +* SegoeKeycaps.ttf +* Segoepr.ttf +* Segoeprb.ttf +* SegoeUIMono-Bold.ttf +* SegoeUIMono-Regular.ttf +* Wscsnbd.ttf +* Wscsnbdit.ttf +* Wscsnit.ttf +* Wscsnrg.ttf + +## Sprite Batching + +In normal drawing, the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) object does not change any render states or draw any sprites until you call [End](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_End). This is known as _Deferred_ mode. In Deferred mode, [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) saves the information from each [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) call until you call [End](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_End). + +If you call [Begin](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__), specifying ```SpriteSortMode.Immediate```, it triggers _Immediate_ mode. In Immediate mode, the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) immediately changes the graphics device render states to begin drawing sprites. Thereafter, each call to [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) immediately draws the sprite using the current device settings. + +In Immediate mode, once you call [Begin](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) on one [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) instance, do not call it on any other [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) instance until you call [End](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_End) for the first [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch). + +Deferred mode is slower than Immediate mode, but it allows multiple instances of [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) to accept [Begin](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) and [Draw](/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Rectangle_Microsoft_Xna_Framework_Color_) calls without interfering with each other. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_StencilBuffer.md b/articles/monogame/whatis/graphics/WhatIs_StencilBuffer.md new file mode 100644 index 0000000..4f2b7b6 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_StencilBuffer.md @@ -0,0 +1,22 @@ +--- +title: What Is a Stencil Buffer? +description: The definition for a Stencil Buffer for MonoGame! +--- + +# What Is a Stencil Buffer? + +A stencil buffer contains per-pixel integer data which is used to add more control over which pixels are rendered. A stencil buffer can also be used in combination with a depth buffer to do more complex rendering such as simple shadows or outlines. + +A stencil buffer operates similarly to a [depth buffer](WhatIs_DepthBuffer.md). So similarly, that stencil data is stored in a depth buffer. While depth data determines which pixel is closest to the camera, stencil data can be used as a more general purpose per-pixel mask for saving or discarding pixels. To create the mask, use a stencil function to compare a reference stencil value -- a global value -- to the value in the stencil buffer each time a pixel is rendered. + +For example, to remove an object from a scene, fill a stencil buffer with a cut out pattern (using zeros) for each pixel where the object is visible. This is done by setting the reference stencil value to 0, clearing the stencil buffer, and rendering the object. Then set the reference stencil value to 1, set the compare function to [CompareFunction.LessEqual](xref:Microsoft.Xna.Framework.Graphics.CompareFunction), and render again. The stencil data masks those pixels whose value is non zero but less than 1, resulting in drawing over (or removing) the object. + +A stencil buffer can be used in more sophisticated ways such as specifying [StencilOperations](xref:Microsoft.Xna.Framework.Graphics.StencilOperation) that go beyond replace or discard and increment or decrement the stencil buffer during a stencil test. Then combine this with a [StencilMask](xref:Microsoft.Xna.Framework.Graphics.DepthStencilState.StencilMask) to mask the portion of the stencil buffer that is updated. + +To use a stencil buffer, the [DepthFormat](xref:Microsoft.Xna.Framework.Graphics.DepthFormat) of the depth buffer must reserve some bits for the stencil data; the [DepthFormat.Depth24Stencil8](/api/Microsoft.Xna.Framework.Graphics.DepthFormat.html) format uses 8 bits for a stencil buffer as an example. Combining stencil data with an 8 bit [DepthStencilState.StencilMask Property](xref:Microsoft.Xna.Framework.Graphics.DepthStencilState.StencilMask) provide up to eight different stencil buffers. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_ViewFrustum.md b/articles/monogame/whatis/graphics/WhatIs_ViewFrustum.md new file mode 100644 index 0000000..e836d5a --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_ViewFrustum.md @@ -0,0 +1,26 @@ +--- +title: What Is a View Frustum? +description: The definition for the View Frustum for MonoGame! +--- + +# What Is a View Frustum? + +A view frustum is a 3D volume that defines how models are projected from camera space to projection space. Objects must be positioned within the 3D volume to be visible. + +The MonoGame Framework uses a projection matrix to calculate a vertex position in the view frustum. The matrix reverses the y-coordinate (so it is top down) to reflect a screen origin at the top-left corner. After the matrix is applied, the homogenous vertices (that is, the vertices contain (x,y,z,w) coordinates) are converted to non-homogeneous coordinates so they can be rasterized. + +The most common type of projection is called a perspective projection, which makes objects near the camera appear bigger than objects in the distance. For a perspective projection, the view frustum can be visualized as a clipped pyramid whose top and bottom are defined by the near and far clipping planes as shown in the figure. + +![A diagram visualisation of the View Frustrum](../images/frustum.jpg) + +A view frustum is defined by a field of view (fov), and by the distances of the front and back clipping planes, which are specified in z-coordinates. Set up a perspective fov using the [CreatePerspectiveFieldOfView](/api/Microsoft.Xna.Framework.Matrix.html#Microsoft_Xna_Framework_Matrix_CreatePerspectiveFieldOfView_System_Single_System_Single_System_Single_System_Single_) method. + +## See Also + +[What Is a Viewport?](WhatIs_Viewport.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/WhatIs_Viewport.md b/articles/monogame/whatis/graphics/WhatIs_Viewport.md new file mode 100644 index 0000000..74e7237 --- /dev/null +++ b/articles/monogame/whatis/graphics/WhatIs_Viewport.md @@ -0,0 +1,34 @@ +--- +title: What Is a Viewport? +description: The definition for the Viewport for MonoGame! +--- + +# What Is a Viewport? + +A viewport is a 2D rectangle that defines the size of the rendering surface onto which a 3D scene is projected. + +A viewport is represented by the [Viewport](xref:Microsoft.Xna.Framework.Graphics.Viewport) class. The **Width** and **Height** properties of the rectangle are used by methods for a variety of calculations such as creating a projection matrix using [CreatePerspectiveFieldOfView](/api/Microsoft.Xna.Framework.Matrix.html#Microsoft_Xna_Framework_Matrix_CreatePerspectiveFieldOfView_System_Single_System_Single_System_Single_System_Single_). Viewport dimensions default to the dimensions of the back buffer, but they can be a different size. For example, to create a split screen game, you might render multiple viewports to a single render target. The viewport dimensions do not correspond to the display dimensions, which are determined by the [DisplayMode](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.DisplayMode) property, or to the game window, which is determined by the [ClientBounds](xref:Microsoft.Xna.Framework.GameWindow.ClientBounds) property. + +Use the [Clear](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_Clear_Microsoft_Xna_Framework_Color_) method to reset a render-target surface. Overloaded versions accept various parameters such as a set of rectangles that define more specific areas rather than the entire surface. Specify in the [ClearOptions](xref:Microsoft.Xna.Framework.Graphics.ClearOptions) enumeration which buffer or render target to reset. + +Use the [Clear](/api/Microsoft.Xna.Framework.Graphics.GraphicsDevice.html#Microsoft_Xna_Framework_Graphics_GraphicsDevice_Clear_Microsoft_Xna_Framework_Color_) method to clear stencil bits within a depth buffer. Set the options parameter to determine which render-target components are cleared. The color argument sets the color value of the render target after it has been cleared. The depth parameter clears the depth buffer to the specified depth: 0.0 is the closest distance, and 1.0 is the farthest. Finally, the stencil parameter resets the stencil bits to the specified value. Use integers ranging from 0 to 2n−1, where _n_ is the stencil buffer bit depth. + +# Desktop Area Versus Display Area + +The size of the desktop area in Windows is shown by the [DisplayMode](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.DisplayMode) **Width** and **Height** properties. The display area is different from the game window, which can be obtained from the [ClientBounds](xref:Microsoft.Xna.Framework.GameWindow.ClientBounds) dimensions. On Windows, set the display mode width and height to match the back buffer width and height. This prevents the need to resize the back buffer when switching between windowed and full screen mode. On Xbox 360, you need to display the text and menu items within the inner 80 percent of the display area. This prevents text or menus from getting cut off at the edge of a television screen. This inner area is called the title safe area. + +The game window size is shown by the [ClientBounds](xref:Microsoft.Xna.Framework.GameWindow.ClientBounds) **Width** and **Height** properties. The game window size matches the display size when a game is running in full-screen mode. The game window size may be smaller for a game running in windowed mode. Use **ClientBounds.X** and **ClientBounds.Y** for the upper-left coordinates of the game window relative to the display area. On Xbox 360, the [ClientBounds](xref:Microsoft.Xna.Framework.GameWindow.ClientBounds) **Width** and **Height** properties are always equal to the [DisplayMode](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.DisplayMode)**Width** and **Height**, and **ClientBounds.X** and **ClientBounds.Y** are always (0, 0). + +**Figure 1.  **DisplayMode** and **ClientBounds** areas on Windows and Xbox 360.** + +![DisplayMode and ClientBounds** areas on Windows and console](../images/viewport.jpg) + +## See Also + +[What Is a Back Buffer?](WhatIs_BackBuffer.md) + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/index.md b/articles/monogame/whatis/graphics/index.md new file mode 100644 index 0000000..68d122c --- /dev/null +++ b/articles/monogame/whatis/graphics/index.md @@ -0,0 +1,80 @@ +--- +title: What are Graphics? +description: The basics of the graphics architecture for MonoGame! +--- + +# Graphical basics 101 + +The topics in this section describe the graphical conventions used by MonoGame in rendering and managing content on a screen. + +## In This Section + +[What Is 3D Rendering?](WhatIs_3DRendering.md) + +The 3D graphics pipeline uses a graphics device to load resources and render a 3D scene using an effect. + +[What Is Antialiasing?](WhatIs_Antialiasing.md) + +Antialiasing is a technique for softening or blurring sharp edges so they appear less jagged when rendered. + +[What Is a Back Buffer?](WhatIs_BackBuffer.md) + +A back buffer is a render target whose contents will be sent to the device when [GraphicsDevice.Present](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Present) is called. + +[What Is Blend State?](WhatIs_BlendState.md) + +Blend state controls how color and alpha values are blended when combining rendered data with existing render target data. + +[What Is Color Blending?](WhatIs_ColorBlending.md) + +Color blending mixes two colors together to produce a third color. + +[What Is a Configurable Effect?](WhatIs_ConfigurableEffect.md) + +A configurable effect is an optimized rendering effect designed for Windows Phone. A configurable effect is created using a built-in object with options for user configuration. + +[What Is a Depth Buffer?](WhatIs_DepthBuffer.md) + +A depth buffer contains per-pixel floating-point data for the z depth of each pixel rendered. A depth buffer may also contain stencil data which can be used to do more complex rendering such as simple shadows or outlines. + +[What Is Depth Stencil State?](WhatIs_DepthStencilState.md) + +Depth stencil state controls how the depth buffer and the stencil buffer are used. + +[What Is a Model Bone?](WhatIs_ModelBone.md) + +A model bone is a matrix that represents the position of a mesh as it relates to other meshes in a 3D model. + +[What Is Rasterizer State?](WhatIs_Rasterizer.md) + +Rasterizer state determines how to render 3D data such as position, color, and texture onto a 2D surface. + +[What Is a Render Target?](WhatIs_Render_Target.md) + +A render target is a memory buffer for rendering pixels. One common use for a render target is offscreen rendering. + +[What Is Sampler State?](WhatIs_Sampler.md) + +Sampler state determines how texture data is sampled using texture addressing modes, filtering, and level of detail. + +[What Is Sprite?](WhatIs_Sprite.md) + +Sprites are 2D bitmaps that are drawn directly to a render target without using the pipeline for transformations, lighting or effects. Sprites are commonly used to display information such as health bars, number of lives, or text such as scores. Some games, especially older games, are composed entirely of sprites. + +[What Is a Stencil Buffer?](WhatIs_StencilBuffer.md) + +A stencil buffer contains per-pixel integer data which is used to add more control over which pixels are rendered. A stencil buffer can also be used in combination with a depth buffer to do more complex rendering such as simple shadows or outlines. + +[What Is a View Frustum?](WhatIs_ViewFrustum.md) + +A view frustum is a 3D volume that defines how models are projected from camera space to projection space. Objects must be positioned within the 3D volume to be visible. + +[What Is a Viewport?](WhatIs_Viewport.md) + +A viewport is a 2D rectangle that defines the size of the rendering surface onto which a 3D scene is projected. + +--- + +© 2012 Microsoft Corporation. All rights reserved. + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/graphics/toc.yml b/articles/monogame/whatis/graphics/toc.yml new file mode 100644 index 0000000..4262931 --- /dev/null +++ b/articles/monogame/whatis/graphics/toc.yml @@ -0,0 +1,2 @@ +- name: Introduction + href: index.md \ No newline at end of file diff --git a/articles/monogame/whatis/images/CP_CustomData.png b/articles/monogame/whatis/images/CP_CustomData.png new file mode 100644 index 0000000..13156b7 Binary files /dev/null and b/articles/monogame/whatis/images/CP_CustomData.png differ diff --git a/articles/monogame/whatis/images/CP_CustomImporter.png b/articles/monogame/whatis/images/CP_CustomImporter.png new file mode 100644 index 0000000..1374a6d Binary files /dev/null and b/articles/monogame/whatis/images/CP_CustomImporter.png differ diff --git a/articles/monogame/whatis/images/ContentPipelineTypes_small.png b/articles/monogame/whatis/images/ContentPipelineTypes_small.png new file mode 100644 index 0000000..2f35106 Binary files /dev/null and b/articles/monogame/whatis/images/ContentPipelineTypes_small.png differ diff --git a/articles/monogame/whatis/images/Model-ModelMesh.png b/articles/monogame/whatis/images/Model-ModelMesh.png new file mode 100644 index 0000000..f996400 Binary files /dev/null and b/articles/monogame/whatis/images/Model-ModelMesh.png differ diff --git a/articles/monogame/whatis/images/blends.jpg b/articles/monogame/whatis/images/blends.jpg new file mode 100644 index 0000000..46736ec Binary files /dev/null and b/articles/monogame/whatis/images/blends.jpg differ diff --git a/articles/monogame/whatis/images/frustum.jpg b/articles/monogame/whatis/images/frustum.jpg new file mode 100644 index 0000000..a60b360 Binary files /dev/null and b/articles/monogame/whatis/images/frustum.jpg differ diff --git a/articles/monogame/whatis/images/viewport.jpg b/articles/monogame/whatis/images/viewport.jpg new file mode 100644 index 0000000..fa5826f Binary files /dev/null and b/articles/monogame/whatis/images/viewport.jpg differ diff --git a/articles/monogame/whatis/index.md b/articles/monogame/whatis/index.md new file mode 100644 index 0000000..cf894a6 --- /dev/null +++ b/articles/monogame/whatis/index.md @@ -0,0 +1,47 @@ +--- +title: "What Is" Articles for MonoGame +description: A series of articles to answer common questions related to MonoGame operation! +requireMSLicense: true +--- + +## In This Section + +[WhatIs Audio?](WhatIs_Audio.md) + +An overview of how the MonoGame Framework provides audio playback through several core audio classes. + +[WhatIs the Content Pipeline?](content_pipeline/index.md) + +An overview of how the MonoGame Framework provides content management and loading for games. + +[WhatIs the Graphics Pipeline?](graphics/index.md) + +An overview of how the MonoGame Framework provides graphical support for games. + +[WhatIs Input?](WhatIs_Input.md) + +An overview of how the MonoGame Framework provides input management for games. + +[What Is a Profile?](WhatIs_Profile.md) + +Provides conceptual information about the MonoGame Framework concept of profiles, including explanations of the Reach and HiDef profiles. + +[What Is the GameLoop?](WhatIs_TheGameLoop.md) + +A viewport is a 2D rectangle that defines the size of the rendering surface onto which a 3D scene is projected. + +[What are Vectors, Matrices, and Quaternions?](WhatIs_VectorMatrixQuat.md) + +Presents an overview of the math-related functionality provided by the MonoGame Framework. + +## See Also + +### References + +[WhatIs MonoGame Class Library](WhatIs_MonoGame_Class_Library.md) + +An overview of the MonoGame Class Library reference, containing all the API calls available to the MonoGame Framework. + +--- + +© 2023 The MonoGame Foundation. diff --git a/articles/monogame/whatis/toc.yml b/articles/monogame/whatis/toc.yml new file mode 100644 index 0000000..b1dc9ff --- /dev/null +++ b/articles/monogame/whatis/toc.yml @@ -0,0 +1,6 @@ +- name: Introduction + href: index.md +- name: Content Pipeline + href: content_pipeline/index.md +- name: Graphics + href: graphics/index.md diff --git a/articles/toc.yml b/articles/toc.yml index bbb4e73..38aa1ae 100644 --- a/articles/toc.yml +++ b/articles/toc.yml @@ -67,4 +67,6 @@ - name: Help and Support href: help_and_support.md - name: Contributing to documentation - href: contributing.md \ No newline at end of file + href: contributing.md +- name: MonoGame + href: monogame/Index.md \ No newline at end of file diff --git a/external/MonoGame b/external/MonoGame index 81ed391..940eb9b 160000 --- a/external/MonoGame +++ b/external/MonoGame @@ -1 +1 @@ -Subproject commit 81ed391a4d0fd81e3ee4bfe2492ad9a0e7f4cfc5 +Subproject commit 940eb9bf3b77a176c429ca528c49eb2f72fbf865